001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core; 015 016import java.io.OutputStream; 017import java.io.PrintStream; 018import java.lang.reflect.Method; 019import java.util.Arrays; 020 021import ch.qos.logback.core.joran.spi.ConsoleTarget; 022import ch.qos.logback.core.status.Status; 023import ch.qos.logback.core.status.WarnStatus; 024import ch.qos.logback.core.util.Loader; 025 026/** 027 * ConsoleAppender appends log events to <code>System.out</code> or 028 * <code>System.err</code> using a layout specified by the user. The default 029 * target is <code>System.out</code>. 030 * <p> 031 * 032 * </p> 033 * For more information about this appender, please refer to the online manual 034 * at http://logback.qos.ch/manual/appenders.html#ConsoleAppender 035 * 036 * @author Ceki Gülcü 037 * @author Tom SH Liu 038 * @author Ruediger Dohna 039 */ 040 041public class ConsoleAppender<E> extends OutputStreamAppender<E> { 042 043 protected ConsoleTarget target = ConsoleTarget.SystemOut; 044 protected boolean withJansi = false; 045 046 private final static String AnsiConsole_CLASS_NAME = "org.fusesource.jansi.AnsiConsole"; 047 private final static String wrapSystemOut_METHOD_NAME = "wrapSystemOut"; 048 private final static String wrapSystemErr_METHOD_NAME = "wrapSystemErr"; 049 private final static Class<?>[] ARGUMENT_TYPES = { PrintStream.class }; 050 051 /** 052 * Sets the value of the <b>Target</b> option. Recognized values are 053 * "System.out" and "System.err". Any other value will be ignored. 054 */ 055 public void setTarget(String value) { 056 ConsoleTarget t = ConsoleTarget.findByName(value.trim()); 057 if (t == null) { 058 targetWarn(value); 059 } else { 060 target = t; 061 } 062 } 063 064 /** 065 * Returns the current value of the <b>target</b> property. The default value of 066 * the option is "System.out". 067 * <p> 068 * See also {@link #setTarget}. 069 */ 070 public String getTarget() { 071 return target.getName(); 072 } 073 074 private void targetWarn(String val) { 075 Status status = new WarnStatus("[" + val + "] should be one of " + Arrays.toString(ConsoleTarget.values()), 076 this); 077 status.add(new WarnStatus("Using previously set target, System.out by default.", this)); 078 addStatus(status); 079 } 080 081 @Override 082 public void start() { 083 OutputStream targetStream = target.getStream(); 084 // enable jansi only if withJansi set to true 085 if (withJansi) { 086 targetStream = wrapWithJansi(targetStream); 087 } 088 setOutputStream(targetStream); 089 super.start(); 090 } 091 092 private OutputStream wrapWithJansi(OutputStream targetStream) { 093 try { 094 addInfo("Enabling JANSI AnsiPrintStream for the console."); 095 ClassLoader classLoader = Loader.getClassLoaderOfObject(context); 096 Class<?> classObj = classLoader.loadClass(AnsiConsole_CLASS_NAME); 097 String methodName = target == ConsoleTarget.SystemOut ? wrapSystemOut_METHOD_NAME 098 : wrapSystemErr_METHOD_NAME; 099 Method method = classObj.getMethod(methodName, ARGUMENT_TYPES); 100 return (OutputStream) method.invoke(null, new PrintStream(targetStream)); 101 } catch (Exception e) { 102 addWarn("Failed to create AnsiPrintStream. Falling back on the default stream.", e); 103 } 104 return targetStream; 105 } 106 107 /** 108 * @return whether to use JANSI or not. 109 */ 110 public boolean isWithJansi() { 111 return withJansi; 112 } 113 114 /** 115 * If true, this appender will output to a stream provided by the JANSI library. 116 * 117 * @param withJansi whether to use JANSI or not. 118 * @since 1.0.5 119 */ 120 public void setWithJansi(boolean withJansi) { 121 this.withJansi = withJansi; 122 } 123 124}