Java 多线程JBehave日志
虽然多线程jBehave运行非常清晰,Java 多线程JBehave日志,java,multithreading,jbehave,Java,Multithreading,Jbehave,虽然多线程jBehave运行非常清晰, 我不清楚如何处理乱七八糟的日志记录 这里有什么选择 将应用程序的输出重新定向到std out(JBehave的输出已经存在)。注意follow=true log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.follow=true log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4
我不清楚如何处理乱七八糟的日志记录 这里有什么选择
follow=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.follow=true
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %-64.64C %4L | %m%n
log4j.rootLogger=error, stdout
log4j.logger.com.company.app.interesting.module=debug
...
@SuppressWarnings("resource")
public class ThreadFileOutput extends PrintStream {
private static ThreadLocal<FileOutputStream> threadOutput = new ThreadLocal<>();
private static PrintStream stdout = System.out;
private static PrintStream stderr = System.err;
static {
System.setOut(new ThreadFileOutput(stdout));
System.setErr(new ThreadFileOutput(stderr));
}
public ThreadFileOutput(OutputStream out) {
super(out);
}
public static void startThreadOutputRedirect(FileOutputStream stream) {
threadOutput.set(stream);
}
public static void stopThreadOutputRedirect() {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
threadOutput.set(null);
try {
stream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static void forceOut(String line) {
stdout.println(line);
}
public static void forceErr(String line) {
stderr.println(line);
}
@Override
public void write(byte[] b) throws IOException {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(b);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(b);
}
}
@Override
public void write(int b) {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(b);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(b);
}
}
@Override
public void write(byte[] buf, int off, int len) {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(buf, off, len);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(buf, off, len);
}
}
@Override
public void flush() {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.flush();
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.flush();
}
}
}
在
奖金-TeamCityReporter(JBehave-to-TC集成)将实时成功统计运行的并行测试,并在TC GUI上报告任何测试失败。将测试输出目录配置为TC工件路径,以访问每个测试输出
follow=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.follow=true
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %-64.64C %4L | %m%n
log4j.rootLogger=error, stdout
log4j.logger.com.company.app.interesting.module=debug
...
@SuppressWarnings("resource")
public class ThreadFileOutput extends PrintStream {
private static ThreadLocal<FileOutputStream> threadOutput = new ThreadLocal<>();
private static PrintStream stdout = System.out;
private static PrintStream stderr = System.err;
static {
System.setOut(new ThreadFileOutput(stdout));
System.setErr(new ThreadFileOutput(stderr));
}
public ThreadFileOutput(OutputStream out) {
super(out);
}
public static void startThreadOutputRedirect(FileOutputStream stream) {
threadOutput.set(stream);
}
public static void stopThreadOutputRedirect() {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
threadOutput.set(null);
try {
stream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static void forceOut(String line) {
stdout.println(line);
}
public static void forceErr(String line) {
stderr.println(line);
}
@Override
public void write(byte[] b) throws IOException {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(b);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(b);
}
}
@Override
public void write(int b) {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(b);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(b);
}
}
@Override
public void write(byte[] buf, int off, int len) {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.write(buf, off, len);
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.write(buf, off, len);
}
}
@Override
public void flush() {
FileOutputStream stream = threadOutput.get();
if (stream != null) {
try {
stream.flush();
} catch (IOException e) {
threadOutput.set(null);
throw new RuntimeException(e);
}
} else {
super.flush();
}
}
}
在
奖金-TeamCityReporter(JBehave-to-TC集成)将实时成功统计运行的并行测试,并在TC GUI上报告任何测试失败。将测试输出目录配置为TC工件路径,以访问每个测试输出
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
...
})
public class Stories extends JUnitStories {
@Before
public void setUp() throws Exception {
configuredEmbedder()
// turn on parallel test execution
.useExecutorService(newFixedThreadPool(30, new ThreadFactoryBuilder()
.setDaemon(true)
.build()));
configuredEmbedder()
.embedderControls()
...
// don't use it this way not to produce multiThreading = true and delayed StoryReporter callbacks
// and you will see your application logging 'for each jbehave step'
// .useThreads(30);
}
@Override
public Configuration configuration() {
return new MostUsefulConfiguration()
...
.useStoryReporterBuilder(new StoryReporterBuilder()
...
.withFormats(HTML)
.withReporters(teamCityReporter));
}
}