SkyWalking Java Agent 日志组件分析

=======

ILog 接口提供了我们常用的打印日志的方法,定义了一套日志使用规范。

/**

  • The Log interface. It’s very easy to understand, like any other log-component. Do just like log4j or log4j2 does.

*/

public interface ILog {

void info(String format);

void info(String format, Object… arguments);

void info(Throwable t, String format, Object… arguments);

void debug(String format);

void debug(String format, Object… arguments);

// 省略部分代码…

}

LogManager

==========

我们看下 LogManager 类的具体实现

/**

  • LogManager is the {@link LogResolver} implementation manager. By using {@link LogResolver}, {@link

  • LogManager#getLogger(Class)} returns a {@link ILog} implementation. This module use this class as the main entrance,

  • and block the implementation detail about log-component. In different modules, like server or sniffer, it will use

  • different implementations.

  • If no {@link LogResolver} is registered, return {@link NoopLogger#INSTANCE} to avoid

  • {@link NullPointerException}. If {@link LogManager#setLogResolver(LogResolver)} is called twice, the second will

  • override the first without any warning or exception.

  • Created by xin on 2016/11/10.

*/

public class LogManager {

private static LogResolver RESOLVER = new PatternLogResolver();

public static void setLogResolver(LogResolver resolver) {

LogManager.RESOLVER = resolver;

}

public static ILog getLogger(Class<?> clazz) {

if (RESOLVER == null) {

return NoopLogger.INSTANCE;

}

return LogManager.RESOLVER.getLogger(clazz);

}

public static ILog getLogger(String clazz) {

if (RESOLVER == null) {

return NoopLogger.INSTANCE;

}

return LogManager.RESOLVER.getLogger(clazz);

}

}

LogManager 类是 LogResolver 实现类的管理器,通过使用 LogResolver,LogManager.getLogger(Class) 返回了 ILog 接口的一个实现,LogManager 类是日志组件的主要入口,内部封装了日志组件的实现细节。

LogManager 内部提供了setLogResolver 方法用于注册指定的 LogResolver,如果设置 LogResolver 为 null,则返回 NoopLogger 实例。

LogResolver 只是返回 ILog 接口的实现

/**

  • {@link LogResolver} just do only one thing: return the {@link ILog} implementation.

*/

public interface LogResolver {

/**

  • @param clazz the class is showed in log message.

  • @return {@link ILog} implementation.

*/

ILog getLogger(Class<?> clazz);

/**

  • @param clazz the class is showed in log message.

  • @return {@link ILog} implementation.

*/

ILog getLogger(String clazz);

}

LogResolver 接口目前提供了2个实现类:PatternLogResolver 、JsonLogResolver 分别返回 PatternLogger 和 JsonLogger。

ILog 接口的实现类

===========

  • NoopLogger 枚举

NoopLogger 直接继承了 ILog,NoopLogger 只是实现了 ILog 接口,所有方法都是空实现,NoopLogger 存在的意义是为了防止 NullPointerException,因为调用者可以通过 LogManager 的 setLogResolver 方法设置不同的日志解析器 LogResolver,如果为null,则返回 ILog 接口的默认实现 NoopLogger。

  • AbstractLogger 抽象类

  • PatternLogger

  • JsonLogger

AbstractLogger

==============

AbstractLogger 抽象类是为了简化 ILog 接口的具体实现,主要功能:

  1. 它持有logger类名 targetClass;

  2. 负责日志级别检查;

  3. 解析用户输入的 message,将{}替换为对应的参数值;

  4. 提供格式化日志内容的抽象方法,需要具体子类实现,目前支持 pattern 和 json 两种,默认为pattern。

输出的日志格式

%level %timestamp %thread %class : %msg %throwable

每一项代表的意义如下:

%level 日志级别.

%timestamp 时间戳 yyyy-MM-dd HH:mm:ss:SSS 格式.

%thread 线程名.

%msg 用户指定的日志信息.

%class 类名.

%throwable 异常信息.

%agent_name agent名称.

对于日志格式中的每一项, SkyWalking Java Agent 分别提供了对应的转换器解析,比如 ThreadConverter、LevelConverter 等。

/**

  • An abstract class to simplify the real implementation of the loggers.

  • It hold the class name of the logger, and is responsible for log level check,

  • message interpolation, etc.

*/

public abstract class AbstractLogger implements ILog {

public static final Map<String, Class<? extends Converter>> DEFAULT_CONVERTER_MAP = new HashMap<>();

protected List converters = new ArrayList<>();

static {

DEFAULT_CONVERTER_MAP.put(“thread”, ThreadConverter.class);

DEFAULT_CONVERTER_MAP.put(“level”, LevelConverter.class);

DEFAULT_CONVERTER_MAP.put(“agent_name”, AgentNameConverter.class);

DEFAULT_CONVERTER_MAP.put(“timestamp”, DateConverter.class);

DEFAULT_CONVERTER_MAP.put(“msg”, MessageConverter.class);

DEFAULT_CONVERTER_MAP.put(“throwable”, ThrowableConverter.class);

DEFAULT_CONVERTER_MAP.put(“class”, ClassConverter.class);

}

// 省略部分代码…

}

比如 ThreadConverter 类用于解析 %thread 输出当前线程的 name。

/**

  • Just return the Thread.currentThread().getName()

*/

public class ThreadConverter implements Converter {

@Override

public String convert(LogEvent logEvent) {

return Thread.currentThread().getName();

}

@Override

public String getKey() {

return “thread”;

}

}

日志格式化 format

============

AbstractLogger 类实现了 ILog 接口,实现了打印日志方法,最终都调用了下面这个通用的方法

protected void logger(LogLevel level, String message, Throwable e) {

WriterFactory.getLogWriter().write(this.format(level, message, e));

}

其中 logger 方法内部调用了 format 方法,format 是一个抽象方法,留给子类去实现日志输出的格式,返回字符串的字符串将输出到文件或标准输出。

/**

  • The abstract method left for real loggers.

  • Any implementation MUST return string, which will be directly transferred to log destination,

  • i.e. log files OR stdout

  • @param level log level

  • @param message log message, which has been interpolated with user-defined parameters.

  • @param e throwable if exists

  • @return string representation of the log, for example, raw json string for {@link JsonLogger}

*/

protected abstract String format(LogLevel level, String message, Throwable e);

抽象类对接口中的方法做了实现,每个实现中都调用了一个抽象方法,这个抽象方法让子类来实现具体的业务逻辑。

下面是 AbstractLogger 抽象类其中一个实现类 PatternLogger 类对 format 方法的实现,调用转换器相应的 Converter ,将日志拼接成字符串。

Kafka进阶篇知识点

image

Kafka高级篇知识点

image

44个Kafka知识点(基础+进阶+高级)解析如下

image

由于篇幅有限,小编已将上面介绍的**《Kafka源码解析与实战》、Kafka面试专题解析、复习学习必备44个Kafka知识点(基础+进阶+高级)都整理成册,全部都是PDF文档**

用了一个抽象方法,这个抽象方法让子类来实现具体的业务逻辑。

下面是 AbstractLogger 抽象类其中一个实现类 PatternLogger 类对 format 方法的实现,调用转换器相应的 Converter ,将日志拼接成字符串。

Kafka进阶篇知识点

[外链图片转存中…(img-vTmHcEUe-1718716211062)]

Kafka高级篇知识点

[外链图片转存中…(img-n0kGIfh1-1718716211063)]

44个Kafka知识点(基础+进阶+高级)解析如下

[外链图片转存中…(img-epYZ6N3y-1718716211063)]

由于篇幅有限,小编已将上面介绍的**《Kafka源码解析与实战》、Kafka面试专题解析、复习学习必备44个Kafka知识点(基础+进阶+高级)都整理成册,全部都是PDF文档**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值