网站建设策划书网页设计,wordpress 极简 模板,html个人网站,h5页面制作网站免费#1 票数#xff1a;41 已采纳使用slf4j无法做到这slf4j 。我想#xff0c;缺少这个功能的原因是#xff0c;几乎不可能为slf4j构建一个Level类型#xff0c;它可以有效地映射到Facade后面所有可能的日志记录实现中使用的Level (或等效)类型。 或者#xff0c;设计…#1 票数41 已采纳使用slf4j无法做到这slf4j 。我想缺少这个功能的原因是几乎不可能为slf4j构建一个Level类型它可以有效地映射到Facade后面所有可能的日志记录实现中使用的Level (或等效)类型。 或者设计人员认为您的用例太不寻常 无法证明支持它的开销。关于 ripper234的用例 (单元测试)我认为实用的解决方案是修改单元测试以便在运行单元测试时强硬了解slf4j外观背后的日志系统。#2 票数25Richard Fearn有正确的想法所以我根据他的骨架代码编写了完整的类。 希望足够短可以在这里发布。 复制和粘贴享受。 我应该添加一些神奇的咒语“此代码发布到公共领域”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;}}#3 票数12尝试切换到Logback并使用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));我相信这将是对Logback的唯一调用其余代码将保持不变。 Logback使用SLF4J迁移将毫不费力只需要更改xml配置文件。记得在完成后重新设置日志级别。#4 票数11您可以使用Java 8 lambdas实现此功能。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 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);}FunctionalInterfaceprivate interface LoggingFunction {public void log(String arg);}}#5 票数6这可以使用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变量例如如果您想要SLF4J的1参数或2参数warn / error /等的通用等价物。 方法。#6 票数5任何想要完全解决此问题的SLF4J兼容解决方案的人都可以查看Lidalia SLF4J扩展 - 它位于Maven Central上。#7 票数2我只是需要这样的东西并提出RequiredArgsConstructor //lombok annotationpublic enum LogLevel{TRACE(l - l::trace),INFO (l - l::info),WARN (l - l::warn),ERROR(l - l::error);private final Function function;public void log(Logger logger, String message) {function.apply(logger).accept(message);}}用法LogLevel level LogLevel.TRACE;level.log(logger, message);Logger在调用期间传递因此类信息应该没问题并且它与 Slf4j lombok注释很好地配合。#8 票数1无法在开箱即用的sjf4j 1.x指定日志级别。 但是slf4j 2.0有希望解决这个问题 。 在2.0中它可能看起来像这样// POTENTIAL 2.0 SOLUTIONimport org.slf4j.helpers.Util;import static org.slf4j.spi.LocationAwareLogger.*;// does not work with slf4j 1.xUtil.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 logMethod;private final Function isEnabledMethod;LogLevel(Function logMethod, Function 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 parameterlevel.prepare(logger).log(Hello {}!, world); // with slf4js parameter replacingtry {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 - Exceptionjava.lang.RuntimeException: Oopsat Application.main(Application.java:14)[main] ERROR Application - logging is enabled这值得么Pro保留源代码位置 (类名方法名行号将指向您的代码)Pro您可以轻松地将变量 参数和返回类型定义为LogLevelPro您的业务代码保持简短易读不需要其他依赖项 。作为最小示例的源代码托管在GitHub上 。#9 票数0我刚刚遇到了类似的需求。 在我的例子中slf4j配置了java日志适配器(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);#10 票数0基于massimo virgilio的答案我还设法使用内省来使用slf4j-log4j。 HTH。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());}#11 票数0这是一个lambda解决方案不像Paul Croarkin那样用户友好(水平有效地传递了两次)。 但我认为(a)用户应该通过Logger; (b)AFAIU原始问题并不是要求应用程序中的任何地方使用方便的方法只是在图书馆内几乎没有使用的情况。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 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 neverthelesslog(LOG::warn, LOG::isWarnEnabled, error doing something: {}, e, e);}}由于slf4j 允许在varargs参数中使用Throwable(其堆栈跟踪应该被记录) 我认为不需要为其他使用者重载log助手方法(String, Object[]) 。#12 票数0我能够通过首先请求SLF4J Logger实例然后在绑定上设置级别来为JDK14绑定执行此操作 - 您可以尝试使用Log4J绑定。private void setLevel(Class loggerClass, java.util.logging.Level level) {org.slf4j.LoggerFactory.getLogger(loggerClass);java.util.logging.Logger.getLogger(loggerClass.getName()).setLevel(level);}#13 票数0我使用的方法是导入ch.qos.logback模块然后将slf4j Logger实例类型转换为ch.qos.logback.classic.Logger。 此实例包含setLevel()方法。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-levellevelSet.setLevel( Level.OFF );要找出可能的日志级别您可以展开ch.qos.logback类以查看Level的所有可能值prompt$ javap -cp logback-classic-1.2.3.jar ch.qos.logback.classic.Level结果如下{// ...skippingpublic 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;}#14 票数0使用slf4j API无法动态更改日志级别但您可以自己配置logback(如果使用此项)。 在这种情况下为您的记录器创建工厂类并使用您需要的配置实现根记录器。LoggerContext loggerContext new LoggerContext();ch.qos.logback.classic.Logger root loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);// Configure appenderfinal 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 messagefinal LayoutWrappingEncoder encoder new LayoutWrappingEncoder();encoder.setCharset(StandardCharsets.UTF_8);encoder.setLayout(layout);final ConsoleAppender 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 logger可以轻松更改日志级别。root.setLevel(Level.DEBUG);#15 票数-2使用java自省可以做到例如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);}}}#16 票数-6不它有很多方法info()debug()warn()等(这取代了优先级字段)ask by Edward Dale translate from so