SLF4J(三) NOP Logger是怎么实现的呢?源码分析

x33g5p2x  于2021-12-28 转载在 其他  
字(2.2k)|赞(0)|评价(0)|浏览(270)

情景

我在之前的文章有提到过这个NOP service provider, 这种provider什么都不做,把日志打到/dev/null, 那它是怎么实现的呢?

代码解析

NOPServiceProvider

我们可以看到这个类除去VERSION字段, 有三个member,这也就是日志的核心组件了

public class NOPServiceProvider implements SLF4JServiceProvider {
	public static String REQUESTED_API_VERSION = "1.8.99"; // !final
	//用于获取logger,处理config,是一个入口,log4j2的部分源码分析
	//可参考[log4j2(三) 如何通过类名获取到logger呢?logger与loggerConfig是什么关系?-源码解析](https://blog.csdn.net/sweetyi/article/details/104653897)
	private ILoggerFactory loggerFactory = new NOPLoggerFactory();
	//给日志打标记时需要用到的,不知道使用场景的话,可以看看这篇文章 
	//[log4j2(一) MarkerFilter的应用场景及使用示例](https://blog.csdn.net/sweetyi/article/details/104547002)
	private IMarkerFactory markerFactory =  new BasicMarkerFactory();
	//相当于是日志的context,常用的场景是往里边放个request id,用于标识没一个请求
	private MDCAdapter mdcAdapter =  new NOPMDCAdapter();
	
	//...省略getter/setter方法
	
	@Override
	public void initialize() {
		// already initialized
	}
}

NOPLoggerFactory

什么都不做!

public class NOPLoggerFactory implements ILoggerFactory {

    public NOPLoggerFactory() {
        // nothing to do
    }
   public Logger getLogger(String name) {
        return NOPLogger.NOP_LOGGER;
    }
}

NOPMDCAdapter

什么都不做!

public class NOPMDCAdapter implements MDCAdapter {

    public void clear() {
    }

    public String get(String key) {
        return null;
    }

    public void put(String key, String val) {
    }

    public void remove(String key) {
    }

    public Map<String, String> getCopyOfContextMap() {
        return null;
    }

    public void setContextMap(Map<String, String> contextMap) {
        // NOP
    }

}

BasicMarkerFactory

这个类到是做了一点点事儿, 就是可以对marker进行增删改查~

public class BasicMarkerFactory implements IMarkerFactory {

    private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<String, Marker>();

    public BasicMarkerFactory() {
    }
    public Marker getMarker(String name) {
        if (name == null) {
            throw new IllegalArgumentException("Marker name cannot be null");
        }

        Marker marker = markerMap.get(name);
        if (marker == null) {
            marker = new BasicMarker(name);
            Marker oldMarker = markerMap.putIfAbsent(name, marker);
            if (oldMarker != null) {
                marker = oldMarker;
            }
        }
        return marker;
    }

    public boolean exists(String name) {
        if (name == null) {
            return false;
        }
        return markerMap.containsKey(name);
    }

    public boolean detachMarker(String name) {
        if (name == null) {
            return false;
        }
        return (markerMap.remove(name) != null);
    }

    public Marker getDetachedMarker(String name) {
        return new BasicMarker(name);
    }

}

总结

“把日志打到/dev/null” 这句话是官方的意思,不熟悉linux的童鞋一看到/dev/null,还不知道以为是个什么高级玩具。其实,读完源码你发现这个NOP就是啥都没做,把你的日志给吞掉了,如此而已。

相关文章