java slf4j日志级别_java - 在slf4j中设置运行时消息的日志级别 - 堆栈内存溢出

===============>>#1 票数:41 已采纳

使用slf4j无法做到这slf4j 。

我想,缺少这个功能的原因是,几乎不可能为slf4j构建一个Level类型,它可以有效地映射到Facade后面所有可能的日志记录实现中使用的Level (或等效)类型。 或者,设计人员认为您的用例太不寻常 ,无法证明支持它的开销。

关于@ ripper234的用例 (单元测试),我认为实用的解决方案是修改单元测试,以便在运行单元测试时强硬了解slf4j外观背后的日志系统。

===============>>#2 票数:25

Richard 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);

}

@FunctionalInterface

private 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 annotation

public 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 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 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 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您的业​​务代码保持简短易读,不需要其他依赖项 。

作为最小示例的源代码托管在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 nevertheless

log(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-level

levelSet.setLevel( Level.OFF );

要找出可能的日志级别,您可以展开ch.qos.logback类以查看Level的所有可能值:

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;

}

===============>>#14 票数:0

使用slf4j API无法动态更改日志级别,但您可以自己配置logback(如果使用此项)。 在这种情况下,为您的记录器创建工厂类,并使用您需要的配置实现根记录器。

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 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Cloudformation集成Spring Boot和EC2

在之前的博客中&#xff0c;我们将Spring Boot应用程序与Elastic beantalk集成在一起。 该应用程序是一个基于Servlet的应用程序&#xff0c;可以响应请求。 在本教程中&#xff0c;我们将部署一个Spring Boot应用程序&#xff0c;该应用程序在ec2实例上执行一些计划的任务。 …

出现$ref的原因及解决方案

$ref的产生原因 &#xff08;1&#xff09;重复引用&#xff1a;一个集合/对象中的多个元素/属性都引用了同一个对象 &#xff08;2&#xff09;循环引用&#xff1a;集合/对象中的多个元素/属性在相互引用导致循环 针对fastjson的处理 fastjson作为一款序列化引擎&#xff0c;…

Wireshark图解教程(简介、抓包、过滤器)

Wireshark是世界上最流行的网络分析工具。这个强大的工具可以捕捉网络中的数据&#xff0c;并为用户提供关于网络和上层协议的各种信息。与很多其他网络工具一样&#xff0c;Wireshark也使用pcap network library来进行封包捕捉。可破解局域网内QQ、邮箱、msn、账号等的密码&am…

php格式书写,PHP书写格式详解(必看)

从一个例子开始。启动编辑器&#xff0c;创建一个php文件并键入如下代码&#xff1a;echo "你好&#xff01;";?>将该文件命名为 test.php 并存储于 E:html 目录下。在浏览器地址栏里访问该 php 文件&#xff1a;http://127.0.0.1/test.php&#xff0c;输出结果如…

java java se_Java SE 11:推动Java前进

java java se介绍 在我看来&#xff0c;这篇文章提出了Java语言应该如何发展成为一种首选语言。 它还提供了一些我喜欢但是有时&#xff08;可能永远不会&#xff09;成为Java的一部分的功能&#xff0c;出于某些原因&#xff0c;我将对此加以解释&#xff0c;这些功能有时我已…

用GDAL/OGR去读shapefile

一、读shapefile 1、首先&#xff0c;用Arcgis创建所要读的shp文件。打开ArcCatalog,右键NEW->Shapefile&#xff0c;名称Name:point &#xff0c;要素类型&#xff08;Feature Type&#xff09;:Point。点击Edit&#xff0c;选择投影类型。 2、打开ArcMap. 单击工具栏里的A…

【日 志】

/// <summary>/// 记录执行sql时的错误日志/// <para>cmdTxt 执行的sql</para>/// <para>inputParams 传入的Hashtable参数</para>/// </summary>private static void LogLastError(string cmdTxt, Hashtable inputParams){try{StringBuil…

php 数组移除指定健,php删除数组指定键的方法

php删除数组指定键的方法&#xff1a;首先创建一个PHP代码示例文件&#xff1b;然后定义一个“array_remove”方法&#xff1b;最后利用“array_key_exists”、“array_search”等函数实现删除数组指定键即可。PHP删除Array数组里指定的key/*** php除数组指定的key值(直接删除k…

Intellij IDEA社区版中的SpringBoot入门

我们可以使用Intellij IDEA社区版来处理SpringBoot应用程序&#xff0c;因为我们不需要配置Tomcat&#xff0c;Wildlfy等服务器&#xff0c;只需运行main&#xff08;&#xff09;方法即可运行应用程序。 但是&#xff0c;Intellij IDEA社区版中没有提供直接创建SpringBoot应用…

SpatialHadoop中空间索引系列之(四)空间格网索引实现

有关空间格网索引原理详见前面章节讲述的内容。这里我们根据SpatialHadoop中具体的实现&#xff0c;来详细讲解下。格网索引是一级索引&#xff0c;格网的个数取决于两个参数&#xff0c;一个是数据集的大小&#xff0c;另外一个就是格网的大小。那么在SpatialHadoop当中&#…

php导入csv文件,php实现CSV文件导入和导出

项目开发中&#xff0c;很多时候要将外部CSV文件导入到数据库中或者将数据导出为CSV文件&#xff0c;那么具体该如何实现呢&#xff1f;本文将使用PHP并结合mysql&#xff0c;实现了CSV格式数据的导入和导出功能。我们先准备mysql数据表&#xff0c;假设项目中有一张记录学生信…

剑指offer-二叉搜索树的后序遍历序列

/*输入一个整数数组&#xff0c;判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。*/ /** 已知条件&#xff1a;后序序列最后一个值为root&#xff1b;二叉搜索树左子树值都比root小&#xff0c;右子树值都…

Nessus漏洞扫描教程之安装Nessus工具

Nessus基础知识 Nessus号称是世界上最流行的漏洞扫描程序&#xff0c;全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务&#xff0c;并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件&#xff0c;Nessus可同时在本机或远端上遥控&#xff0c;进行系…

php强制关机代码,程序员关机代码是什么?

程序员关机代码&#xff1a;1、定时关机&#xff0c;在运行中输入【at 22:00 Shutdown -s】&#xff1b;2、倒计时方式关机&#xff0c;在运行中输入【Shutdown.exe -s -t 3600】&#xff1b;3、自动关机&#xff0c;输入【shutdown -i】。程序员关机代码&#xff1a;1、比如你…

Java 9和应用程序性能监视的激动人心之处

通过AppDynamics解决应用程序问题的速度提高了10倍–以最小的开销在代码级深度监视生产应用程序。 开始免费试用&#xff01; 在当今的现代计算时代&#xff0c;软件创新的不断增强使我们更接近软件革命的时代。 也许在遥远的未来&#xff0c;这可能是对21世纪记忆犹新的方式。…

GPU下train 模型出现nan

When training on GPU, the error "Model diverged with loss NaN" is often caused by a sotmax thats getting a symbol larger than vocab_size 转载于:https://www.cnblogs.com/wuxiangli/p/10344259.html

php语言的四种循环控制语句,PHP循环控制语句

循环语句的作用就是在条件满足的情况下&#xff0c;可以执行多次相同或相似的任务&#xff0c;PHP中的循环语句包括for、while、do-while和foreach语句结构&#xff0c;下面分别介绍。for语句for语句结构一般用于执行确定循环次数的操作&#xff0c;其条件包括三个部分&#xf…

Kali linux安装漏洞扫描工具Nessus安装指南

引子&#xff1a;Nessus是著名信息安全服务公司tenable推出的一款漏洞扫描与分析软件&#xff0c;号称是"世界上最流行的漏洞扫描程序,全世界超过75,000个组织在使用它"。尽管这个扫描程序可以免费下载得到&#xff0c;但是要从Tenable更新到所有最新的威胁信息,每年…

7.9 规划Varnish缓存

./varnishlog -i VCL_LOG 转载于:https://www.cnblogs.com/likevin/p/10337069.html

php详解递归,PHP递归算法详解

本篇文章主要介绍PHP递归算法详解&#xff0c;感兴趣的朋友参考下&#xff0c;希望对大家有所帮助。遇到需要设计树节点的数据库结构&#xff0c;以及需要读出来的树节点数据结构&#xff01;大家是否会选择用数据库的查询方式来获取树结构呢&#xff1f;//曾经的数据库查询获取…