我目前正在观察第三方库(即restfb)正在使用java.util.logging并且我看到这些日志最终在STDOUT中,即使我没有在我的logback.xml中配置SLF4J控制台appender.我的classpath中也有jul-to-slf4j桥.jul-to-slf4j网桥是否仅在安装网桥时登录到由logback配置的appender,还是还记录到stdout?
我有以下Logger我想模拟,但验证日志条目被调用,而不是内容.
private static Logger logger =
LoggerFactory.getLogger(GoodbyeController.class);
Run Code Online (Sandbox Code Playgroud)
我想模拟用于LoggerFactory.getLogger()的任何类,但我无法找到如何做到这一点.这是我到目前为止所得到的:
@Before
public void performBeforeEachTest() {
PowerMockito.mockStatic(LoggerFactory.class);
when(LoggerFactory.getLogger(GoodbyeController.class)).
thenReturn(loggerMock);
when(loggerMock.isDebugEnabled()).thenReturn(true);
doNothing().when(loggerMock).error(any(String.class));
...
}
Run Code Online (Sandbox Code Playgroud)
我想知道:
LoggerFactory.getLogger()以适用于任何类吗?when(loggerMock.isDebugEnabled()).thenReturn(true);的@Before,因此我似乎无法改变每个方法的特点.有没有解决的办法?编辑发现:
我以为我已经尝试了这个并且它没有用:
when(LoggerFactory.getLogger(any(Class.class))).thenReturn(loggerMock);
Run Code Online (Sandbox Code Playgroud)
但是,谢谢你,因为它确实有效.
但是我尝试了无数的变化:
when(loggerMock.isDebugEnabled()).thenReturn(true);
Run Code Online (Sandbox Code Playgroud)
我不能让loggerMock改变它的行为,@Before但这只发生在Coburtura上.使用Clover,覆盖率显示为100%,但仍然存在问题.
我有这个简单的课程:
public ExampleService{
private static final Logger logger =
LoggerFactory.getLogger(ExampleService.class);
public String getMessage() {
if(logger.isDebugEnabled()){
logger.debug("isDebugEnabled");
logger.debug("isDebugEnabled");
}
return "Hello world!";
}
...
}
Run Code Online (Sandbox Code Playgroud)
然后我有这个测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({LoggerFactory.class})
public class ExampleServiceTests {
@Mock
private Logger loggerMock;
private ExampleServiceservice = new ExampleService();
@Before
public …Run Code Online (Sandbox Code Playgroud) 我有跟随进口:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Run Code Online (Sandbox Code Playgroud)
以及以下实例:
private static Logger logger = LoggerFactory.getLogger(Test.class);
Run Code Online (Sandbox Code Playgroud)
以及我的Main方法中的以下内容:
logger.info("SOME MESSAGE: ");
Run Code Online (Sandbox Code Playgroud)
但是,我无法在任何地方找到输出.我只看到在我的控制台中有:
21:21:24.235 [main] INFO some_folder.Test - SOME MESSAGE:
Run Code Online (Sandbox Code Playgroud)
如何找到日志文件?
请注意,以下内容位于我的构建路径中:
slf4j-api-1.7.5.jar
slf4j-log4j12-1.6.4.jar
我读了类似问题的答案,但没有人真正说明如何解决问题.
slf4j-log4j12和log4j-over-slf4j之间有什么区别?何时应该使用它们?
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.12</version>
</dependency>
Run Code Online (Sandbox Code Playgroud) 我的问题似乎很容易回答,但有几个很好的解决方案.我喜欢选择"最好的".
logger.debug("Some log message. Details: {}", someObject.toString());是跳过字符串连接,如果记录器被关闭一个良好的,有效的途径; 委托给的轻量级记录器绑定android.util.Log.com.example.myapp.MyClass转换为标记c*.e*.m*.MyClass),自动生成的日志标记长度<= 23个字符,这可能导致不同类的相同日志标记(例如,com.example.app.MyClass并且com.example.anotherapp.MyClass都翻译to c*.e*.a*.MyClass); 没有内置的崩溃报告系统.除了这些,我喜欢Androlog行为,但我是一个Java开发人员,熟悉log4j/slf4j.我们肯定需要崩溃报告系统,但有几个崩溃报告框架(除了android默认崩溃报告).
我可以结合其中的一些,例如使用Log4J android,但是创建一个appender来使用androlog框架,但迟早会是一团糟,应该避免.
感谢您的建议,我希望结果将有助于将来决定其他人.
编辑:如下所述,我可以结合ex:log4j-android与slf4j(如果我将使用log4j,我更喜欢做什么,因为日志格式支持("{}",...)),但它确实如此没有回答这个问题.我必须选择一个框架,然后我可以用SLF4J外观装饰它.
堆栈跟踪被截断 - 例如它们以 [info] ...
使用last或更改traceLevel没有帮助 - 它只是打印sbt包装器的完整堆栈跟踪.
这是用testng测试的(我也相信使用scalatest和sl4j)
SLF4J的"Hello World"示例对我不起作用.我想这是因为我将slf4j-log4添加到了我的类路径中.我应该直接配置log4j以使hello world工作吗?
log4j:WARN No appenders could be found for logger (HelloWorld).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Run Code Online (Sandbox Code Playgroud)
更新:我添加了log4j初始化,它仍然无法正常工作:
public static void main(String[] params) {
org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender());
Logger logger = org.slf4j.LoggerFactory.getLogger(TestBase.class);
logger.info("Hello World");
}
Run Code Online (Sandbox Code Playgroud)
我得到了:
log4j:ERROR No output stream or file set for the appender named [null].
Run Code Online (Sandbox Code Playgroud) 是否有可能以某种方式拦截日志记录(SLF4J + logback)并InputStream通过JUnit测试用例获取(或其他可读的内容)......?
似乎log4j有一些类加载问题(等等),在我看来趋势是从log4j移出slf4j.(Hibernate停止使用第一个支持后者)
更新:
您似乎偶然发现了log4j(以及Apache Commons Logging库)的主要问题,即他们在使用时发现并与正确的类加载器进行交互时非常困难.这里有一个非常密集的解释,有完整的例子; 带回家的信息是,新的日志框架SLF4J的主要推动力之一就是完全消除这些问题.你可能想要交换它,看看你的生活是否变得更容易.
我使用slf4j来跟踪信息.我的代码是
private static final Logger log = LoggerFactory.getLogger(ObjectTest.class);
log.trace("Time taken to store " + count
+ " objects of size " + size + " is " + (time) + " msecs");
log.trace("Time taken to store {} objects of size {} is {} msecs",
new Object[] { count, size, time });
log.trace("Time taken to store {} objects of size {} is {} msecs",
count, size, time);
Run Code Online (Sandbox Code Playgroud)
这将是记录跟踪的首选机制.