做软件开发要培养一个很值钱的习惯:打日志。打日志可以记录程序正确运行的结果,也可以记录错误运行的结果,更可以根据需要,有选择性的记录程序运行的细节问题,或关键性信息。这些信息并不关注阅读者是否能懂,但一定很有价值。
习惯了spring
、SpringBoot
或lombok
方便的日志,RCP
日志该如何打印呢?
获取日志打印器
一般地,创建RCP都生成了Activator.java
,只需要在该方法中添加如下代码。
public static ILog getLogger() {
return getDefault().getLog();
}
完整方法如下,其中main
方法是为了方便写测试而写的,运行会报错。
package com.xzbd.advisor;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class AppActivator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.xzbd.rcp02";
// The shared instance
private static AppActivator plugin;
/**
* Returns the shared instance
*/
public static AppActivator getDefault() {
return plugin;
}
public AppActivator() {
}
/*
* 启动,并给plugin赋值
* ……
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* 停止并销毁plugin
* ……
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* get plugin
* <p>手动新增</p>
* @return
*/
public static ILog getLogger() {
return getDefault().getLog();
}
/**
* test 测试
* <p>手动新增</p>
* @return
*/
public static void main(String[] args) {
ILog logger = AppActivator.getLogger();
logger.info("info msg");
logger.error("error msg");
// logger.log(status);
//
}
/**
* Returns an image descriptor for the image file at the given
* ……
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}
为什么运行main
会报错?因为程序未启动,start
函数未执行,plugin
为null。
拓展
- logger 其实定义在
org.eclipse.core.runtime
下Plugin
中,其源码如下
/**
* Returns the log for this plug-in. If no such log exists, one is created.
* ……
*/
public final ILog getLog() {
return InternalPlatform.getDefault().getLog(getBundle());
}
- logger 是需要你开发的插件(
plugin
)实例化后才能使用。前面已经解释,同学阅读源码也很容易理解。 - logger 默认提供了四种日志方法
// logger.log(status);
logger.info("info msg");
logger.warn("warn msg");
logger.error("error msg");
其中 log
是基础方法,info
和 error
是基于log
实现。ILog
中实现如下:
/**
* Logs a status with {@link IStatus#INFO} using this logger
* ……
* @since 3.17
*/
default void info(String message) {
log(new Status(IStatus.INFO, getBundle().getSymbolicName(), message));
}
/**
* Logs a status with {@link IStatus#INFO} using this logger
* ……
* @since 3.17
*/
default void info(String message, Throwable throwable) {
log(new Status(IStatus.INFO, getBundle().getSymbolicName(), message, throwable));
}
/**
* Logs a status with {@link IStatus#WARNING} using this logger
* ……
* @since 3.17
*/
default void warn(String message) {
log(new Status(IStatus.WARNING, getBundle().getSymbolicName(), message));
}
/**
* Logs a status with {@link IStatus#WARNING} using this logger
* ……
* @since 3.17
*/
default void warn(String message, Throwable throwable) {
log(new Status(IStatus.WARNING, getBundle().getSymbolicName(), message, throwable));
}
/**
* Logs a status with {@link IStatus#ERROR} using this logger
* ……
* @since 3.17
*/
default void error(String message) {
log(new Status(IStatus.ERROR, getBundle().getSymbolicName(), message));
}
/**
* Logs a status with {@link IStatus#ERROR} using this logger
* ……
* @since 3.17
*/
default void error(String message, Throwable throwable) {
log(new Status(IStatus.ERROR, getBundle().getSymbolicName(), message, throwable));
}
- 结合
IStatus
很容易扩展logger
,形成项目自己的logger
工具类。
IStatus
提供的
package org.eclipse.core.runtime;
/**
* A status object represents the outcome of an operation.
* All <code>CoreException</code>s carry a status object to indicate
* what went wrong. Status objects are also returned by methods needing
* to provide details of failures (e.g., validation methods).
**/
public interface IStatus {
public static final int OK = 0;
public static final int INFO = 0x01;
public static final int WARNING = 0x02;
public static final int ERROR = 0x04;
public static final int CANCEL = 0x08;
public IStatus[] getChildren();
public int getCode();
public Throwable getException();
public String getMessage();
public String getPlugin();
public int getSeverity();
public boolean isMultiStatus();
public boolean isOK();
public boolean matches(int severityMask);
}
官方案例
参考 WorkbenchPlugin
中 log 的实现。
自定义工具包
public class LogUtil {
/**
* get plugin logger
* @return
*/
public static ILog getPluginLogger() {
return Activator.getDefault().getLog();
}
/**
* out info message
* @param message
*/
public static void info(String message) {
getPluginLogger().info(message);
}
/**
* out info message
* @param message
*/
public static void info(String prifix,String message) {
getPluginLogger().info(concatMsg(prifix,message));
}
/**
* out warn message
* @param message
*/
public static void warn(String message) {
getPluginLogger().warn(message);
}
/**
* out warn message
* @param message
*/
public static void warn(String prifix,String message) {
getPluginLogger().warn(concatMsg(prifix,message));
}
/**
* out info message
* @param message
*/
public static void error(String message) {
getPluginLogger().error(message);
}
/**
* out error message
* @param message
*/
public static void error(String prifix,String message) {
getPluginLogger().error(concatMsg(prifix,message));
}
/**
* out error and print exception
* @param message
* @param e
*/
public static void error(String message,Exception e) {
getPluginLogger().error(message);
e.printStackTrace();
}
/**
* out error and print exception
* @param message
* @param e
*/
public static void error(String prifix,String message,Exception e) {
getPluginLogger().error(concatMsg(prifix,message));
e.printStackTrace();
}
private static String concatMsg(String prifix,String message) {
String tmpMsg = "";
if(StringUtils.isNotBlank(prifix)) {
tmpMsg = "【"+ prifix+"】:";
}
tmpMsg = tmpMsg + message;
return tmpMsg;
}
}