1 用sl4j(采用门面模式,不提供实现,且提供占位符打印的方式)
2 过长的内容没有意义,集合最多打印几十个
3 如果有字符串拼接或者toJSON的情况,打印log之前判断该级别是否开启,不然会白白浪费cpu
4 对于第3点可优化的地方,用下面的util,配合着sl4j,这样就不用写判断日志级别是否开启的代码了
1 2 3 4 5 6 7 8 9 10 11 12 13
| public abstract class LogUtils {
public static LogUtils lazyJson(Object object) { return new LogUtils() { String json = null; @Override public String toString() { return json != null ? json : (json = JSON.toJSONString(object, JSONMaxSerializeConfig.MAX_100_SERIALIZE_CONFIG)); } }; } }
|
例如:
1
| log.info("我要打印一个实体,想在开启info级别的情况下toJSON,还不想写if代码,并且实体里面有集合类型字段的话,最多输出100长度即可:{}", LogUtils.lazyJson(实体));
|
限制序列化的长度
日志过多过长也就没有了意义,所以如果是集合类型,我们只打印前100几个,输出过多的日志非常影响服务器性能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| @Slf4j public class JSONMaxSerializeConfig extends SerializeConfig {
public static final JSONMaxSerializeConfig MAX_100_SERIALIZE_CONFIG = new JSONMaxSerializeConfig(100);
private final int MAX_SERIALIZE_NUM;
public JSONMaxSerializeConfig(int MAX_SERIALIZE_NUM) { super(true); this.MAX_SERIALIZE_NUM = MAX_SERIALIZE_NUM; this.register(new Module() {
@Override public ObjectDeserializer createDeserializer(ParserConfig parserConfig, Class aClass) { return null; }
@Override public ObjectSerializer createSerializer(SerializeConfig serializeConfig, Class aClass) {
if (AbstractList.class.isAssignableFrom(aClass)) { return ABSTRACT_LIST_SERIALIZER; }
if (AbstractSet.class.isAssignableFrom(aClass)) { return ABSTRACT_SET_SERIALIZER; } return null; } }); }
private final ObjectSerializer ABSTRACT_LIST_SERIALIZER = (jsonSerializer, o, o1, type, i) -> { AbstractList<?> list = (AbstractList<?>) o; ListSerializer.instance.write(jsonSerializer, new AbstractList<Object>() { public int size() { if (list.size() > MAX_SERIALIZE_NUM) { log.warn("序列化输出已超出最大限制,后续的序列化将要舍弃,实际大小:{}, max:{}", list.size(), MAX_SERIALIZE_NUM); } return Math.min(list.size(), MAX_SERIALIZE_NUM); }
public Object get(int index) { return list.get(index); } }, o1, type, i); };
private final ObjectSerializer ABSTRACT_SET_SERIALIZER = (jsonSerializer, o, o1, type, i) -> { @SuppressWarnings("unchecked") AbstractSet<Object> set = (AbstractSet<Object>) o; CollectionCodec.instance.write(jsonSerializer, new AbstractSet<Object>() { public Iterator<Object> iterator() { return new Iterator<Object>() { final Iterator<?> originIterator = set.iterator(); int count = 1;
public boolean hasNext() { count++; if (count > MAX_SERIALIZE_NUM) { log.warn("序列化输出已超出最大限制,后续的序列化将要舍弃, max:{}", MAX_SERIALIZE_NUM); } return count <= MAX_SERIALIZE_NUM && originIterator.hasNext(); }
public Object next() { return originIterator.next(); } }; }
public int size() { return Math.min(set.size(), MAX_SERIALIZE_NUM); } }, o1, type, i); }; }
|