Springboot 中的Log处理

SpringBoot 中的log 源码分析:
加载配置文件

 */
class JavaLoggingSystemRuntimeHints implements RuntimeHintsRegistrar {

	@Override
	public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
		hints.resources().registerPattern("org/springframework/boot/logging/java/logging.properties");
		hints.resources().registerPattern("org/springframework/boot/logging/java/logging-file.properties");
	}

}

SimpleFormatter :

public class SimpleFormatter extends Formatter {

	private static final String DEFAULT_FORMAT = "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL] - %8$s %4$s [%7$s] --- %3$s: %5$s%6$s%n";

	private final String format = getOrUseDefault("LOG_FORMAT", DEFAULT_FORMAT);

	private final String pid = getOrUseDefault(LoggingSystemProperties.PID_KEY, "????");

	private final Date date = new Date();

	@Override
	public synchronized String format(LogRecord record) {
		this.date.setTime(record.getMillis());
		String source = record.getLoggerName();
		String message = formatMessage(record);
		String throwable = getThrowable(record);
		String thread = getThreadName();
		return String.format(this.format, this.date, source, record.getLoggerName(),
				record.getLevel().getLocalizedName(), message, throwable, thread, this.pid);
	}

	private String getThrowable(LogRecord record) {
		if (record.getThrown() == null) {
			return "";
		}
		StringWriter stringWriter = new StringWriter();
		PrintWriter printWriter = new PrintWriter(stringWriter);
		printWriter.println();
		record.getThrown().printStackTrace(printWriter);
		printWriter.close();
		return stringWriter.toString();
	}

	private String getThreadName() {
		String name = Thread.currentThread().getName();
		return (name != null) ? name : "";
	}

	private static String getOrUseDefault(String key, String defaultValue) {
		String value = null;
		try {
			value = System.getenv(key);
		}
		catch (Exception ex) {
			// ignore
		}
		if (value == null) {
			value = defaultValue;
		}
		return System.getProperty(key, value);
	}

}
public class SpringBootPropertySource implements PropertySource {

	private static final String PREFIX = "log4j.";

	private final Map<String, String> properties = Collections
			.singletonMap(ShutdownCallbackRegistry.SHUTDOWN_HOOK_ENABLED, "false");

	@Override
	public void forEach(BiConsumer<String, String> action) {
		this.properties.forEach(action::accept);
	}

	@Override
	public CharSequence getNormalForm(Iterable<? extends CharSequence> tokens) {
		return PREFIX + Util.joinAsCamelCase(tokens);
	}

	@Override
	public int getPriority() {
		return -200;
	}

	@Override
	public String getProperty(String key) {
		return this.properties.get(key);
	}

	@Override
	public boolean containsProperty(String key) {
		return this.properties.containsKey(key);
	}

	@Override
	public Collection<String> getPropertyNames() {
		return this.properties.keySet();
	}

}

@Plugin(name = "SpringBootConfigurationFactory", category = ConfigurationFactory.CATEGORY)
@Order(0)
public class SpringBootConfigurationFactory extends ConfigurationFactory {

	private static final String[] TYPES = { ".springboot" };

	@Override
	protected String[] getSupportedTypes() {
		return TYPES;
	}

	@Override
	public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
		if (source == null || source == ConfigurationSource.NULL_SOURCE) {
			return null;
		}
		return new DefaultConfiguration();
	}

}

其中logback 的用法如下:

public abstract class AbstractLoggingSystem extends LoggingSystem {

	protected static final Comparator<LoggerConfiguration> CONFIGURATION_COMPARATOR = new LoggerConfigurationComparator(
			ROOT_LOGGER_NAME);

	private final ClassLoader classLoader;

	public AbstractLoggingSystem(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}

	@Override
	public void beforeInitialize() {
	}

	@Override
	public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
		if (StringUtils.hasLength(configLocation)) {
			initializeWithSpecificConfig(initializationContext, configLocation, logFile);
			return;
		}
		initializeWithConventions(initializationContext, logFile);
	}

	private void initializeWithSpecificConfig(LoggingInitializationContext initializationContext, String configLocation,
			LogFile logFile) {
		configLocation = SystemPropertyUtils.resolvePlaceholders(configLocation);
		loadConfiguration(initializationContext, configLocation, logFile);
	}

	private void initializeWithConventions(LoggingInitializationContext initializationContext, LogFile logFile) {
		String config = getSelfInitializationConfig();
		if (config != null && logFile == null) {
			// self initialization has occurred, reinitialize in case of property changes
			reinitialize(initializationContext);
			return;
		}
		if (config == null) {
			config = getSpringInitializationConfig();
		}
		if (config != null) {
			loadConfiguration(initializationContext, config, logFile);
			return;
		}
		loadDefaults(initializationContext, logFile);
	}

	/**
	 * Return any self initialization config that has been applied. By default this method
	 * checks {@link #getStandardConfigLocations()} and assumes that any file that exists
	 * will have been applied.
	 * @return the self initialization config or {@code null}
	 */
	protected String getSelfInitializationConfig() {
		return findConfig(getStandardConfigLocations());
	}

	/**
	 * Return any spring specific initialization config that should be applied. By default
	 * this method checks {@link #getSpringConfigLocations()}.
	 * @return the spring initialization config or {@code null}
	 */
	protected String getSpringInitializationConfig() {
		return findConfig(getSpringConfigLocations());
	}

	private String findConfig(String[] locations) {
		for (String location : locations) {
			ClassPathResource resource = new ClassPathResource(location, this.classLoader);
			if (resource.exists()) {
				return "classpath:" + location;
			}
		}
		return null;
	}

	/**
	 * Return the standard config locations for this system.
	 * @return the standard config locations
	 * @see #getSelfInitializationConfig()
	 */
	protected abstract String[] getStandardConfigLocations();

	/**
	 * Return the spring config locations for this system. By default this method returns
	 * a set of locations based on {@link #getStandardConfigLocations()}.
	 * @return the spring config locations
	 * @see #getSpringInitializationConfig()
	 */
	protected String[] getSpringConfigLocations() {
		String[] locations = getStandardConfigLocations();
		for (int i = 0; i < locations.length; i++) {
			String extension = StringUtils.getFilenameExtension(locations[i]);
			locations[i] = locations[i].substring(0, locations[i].length() - extension.length() - 1) + "-spring."
					+ extension;
		}
		return locations;
	}

	/**
	 * Load sensible defaults for the logging system.
	 * @param initializationContext the logging initialization context
	 * @param logFile the file to load or {@code null} if no log file is to be written
	 */
	protected abstract void loadDefaults(LoggingInitializationContext initializationContext, LogFile logFile);

	/**
	 * Load a specific configuration.
	 * @param initializationContext the logging initialization context
	 * @param location the location of the configuration to load (never {@code null})
	 * @param logFile the file to load or {@code null} if no log file is to be written
	 */
	protected abstract void loadConfiguration(LoggingInitializationContext initializationContext, String location,
			LogFile logFile);

	/**
	 * Reinitialize the logging system if required. Called when
	 * {@link #getSelfInitializationConfig()} is used and the log file hasn't changed. May
	 * be used to reload configuration (for example to pick up additional System
	 * properties).
	 * @param initializationContext the logging initialization context
	 */
	protected void reinitialize(LoggingInitializationContext initializationContext) {
	}

	protected final ClassLoader getClassLoader() {
		return this.classLoader;
	}

	protected final String getPackagedConfigFile(String fileName) {
		String defaultPath = ClassUtils.getPackageName(getClass());
		defaultPath = defaultPath.replace('.', '/');
		defaultPath = defaultPath + "/" + fileName;
		defaultPath = "classpath:" + defaultPath;
		return defaultPath;
	}

	protected final void applySystemProperties(Environment environment, LogFile logFile) {
		new LoggingSystemProperties(environment).apply(logFile);
	}

	/**
	 * Maintains a mapping between native levels and {@link LogLevel}.
	 *
	 * @param <T> the native level type
	 */
	protected static class LogLevels<T> {

		private final Map<LogLevel, T> systemToNative;

		private final Map<T, LogLevel> nativeToSystem;

		public LogLevels() {
			this.systemToNative = new EnumMap<>(LogLevel.class);
			this.nativeToSystem = new HashMap<>();
		}

		public void map(LogLevel system, T nativeLevel) {
			this.systemToNative.putIfAbsent(system, nativeLevel);
			this.nativeToSystem.putIfAbsent(nativeLevel, system);
		}

		public LogLevel convertNativeToSystem(T level) {
			return this.nativeToSystem.get(level);
		}

		public T convertSystemToNative(LogLevel level) {
			return this.systemToNative.get(level);
		}

		public Set<LogLevel> getSupported() {
			return new LinkedHashSet<>(this.nativeToSystem.values());
		}

	}

}

deferedLogs:

public class DeferredLogs implements DeferredLogFactory {

	private final Lines lines = new Lines();

	private final List<DeferredLog> loggers = new ArrayList<>();

	/**
	 * Create a new {@link DeferredLog} for the given destination.
	 * @param destination the ultimate log destination
	 * @return a deferred log instance that will switch to the destination when
	 * appropriate.
	 */
	@Override
	public Log getLog(Class<?> destination) {
		return getLog(() -> LogFactory.getLog(destination));
	}

	/**
	 * Create a new {@link DeferredLog} for the given destination.
	 * @param destination the ultimate log destination
	 * @return a deferred log instance that will switch to the destination when
	 * appropriate.
	 */
	@Override
	public Log getLog(Log destination) {
		return getLog(() -> destination);
	}

	/**
	 * Create a new {@link DeferredLog} for the given destination.
	 * @param destination the ultimate log destination
	 * @return a deferred log instance that will switch to the destination when
	 * appropriate.
	 */
	@Override
	public Log getLog(Supplier<Log> destination) {
		synchronized (this.lines) {
			DeferredLog logger = new DeferredLog(destination, this.lines);
			this.loggers.add(logger);
			return logger;
		}
	}

	/**
	 * Switch over all deferred logs to their supplied destination.
	 */
	public void switchOverAll() {
		synchronized (this.lines) {
			for (Line line : this.lines) {
				DeferredLog.logTo(line.getDestination(), line.getLevel(), line.getMessage(), line.getThrowable());
			}
			for (DeferredLog logger : this.loggers) {
				logger.switchOver();
			}
			this.lines.clear();
		}

	}

}

SprigBoot 中的log 处理:
Java Util Logging
Logging
Log4j2
Logback(默认)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值