参考Hadoop源码 实现项目启动和停止时,输出项目版本信息工具

读过Hadoop源码的人一定不陌生,其实就是借鉴Hadoop源码里的启动工具类。

只不过Hadoop源码是用package-info.java来实现。

原理大致一样,通过打包脚本,在maven打包之前生成相关的信息载体文件放入项目资源文件中,然后进行maven打包。

项目启动时,加载资源文件到VersionInfo信息类中,给消息输出工具类进行使用。

由于工作中的项目是通过生成txt的版本文件而不是package-info.java文件,所以进行了修改。

具体的代码可以参考Hadoop源码里的org.apache.hadoop.hdfs.server.namenode.NameNode的main方法。

调用方式

public class TEST {
    private static Logger LOG = LoggerFactory.getLogger(TEST.class.getName());

    public static void main(String[] args) {

        MessagesUtils.startupShutdownMessage(TEST.class, args, LOG);

        // 处理后续业务逻辑
        // ......
    }
}

工具类

package com.hyr;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/*******************************************************************************
 * @date 2018-11-30 下午 4:23
 * @author: <a href=mailto:>黄跃然</a>
 * @Description: 消息工具类
 ******************************************************************************/
public class MessagesUtils {

    /**
     * 启动/关闭 消息打印
     *
     * @param clazz 启动clazz
     * @param args
     * @param LOG
     */
    public static void startupShutdownMessage(Class<?> clazz, String[] args, final org.slf4j.Logger LOG) {
        final String hostname = getHostname();
        final String classname = clazz.getSimpleName();

        LOG.info(
                getMessageInfo(args, hostname, classname)
        );

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                LOG.info(toStartupShutdownString("SHUTDOWN MESSAGE: ", new String[]{
                        "Shutting down " + classname + " at " + hostname}));
            }
        });
    }

    /**
     * 启动/关闭 消息打印
     *
     * @param clazz 启动clazz
     * @param args
     * @param LOG
     */
    public static void startupShutdownMessage(Class<?> clazz, String[] args, final org.apache.log4j.Logger LOG) {
        final String hostname = getHostname();
        final String classname = clazz.getSimpleName();

        LOG.info(
                getMessageInfo(args, hostname, classname)
        );

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                LOG.info(toStartupShutdownString("SHUTDOWN MESSAGE: ", new String[]{
                        "Shutting down " + classname + " at " + hostname}));
            }
        });
    }


    /**
     * Return a message for logging.
     *
     * @param prefix prefix keyword for the message
     * @param msg    content of the message
     * @return a message for logging
     */
    private static String toStartupShutdownString(String prefix, String[] msg) {
        StringBuilder b = new StringBuilder("\n" + prefix);
        b.append("\n/************************************************************");
        for (String s : msg)
            b.append("\n").append(prefix).append(s);
        b.append("\n************************************************************/");
        return b.toString();
    }

    /**
     * 日志详情
     *
     * @param args
     * @param hostname
     * @param classname
     * @return
     */
    private static String getMessageInfo(String[] args, String hostname, String classname) {
        return toStartupShutdownString("START_UP MESSAGE: ", new String[]{
                "  Starting " + classname,
                "  host = " + hostname,
                "  args = " + Arrays.asList(args),
                "  version = " + BrowserVersionInfo.getProjectVersion(),
                "  compiled time = " + BrowserVersionInfo.getCompiledTime(),
                "  revision = " + BrowserVersionInfo.getSVNVersion(),
                "  java = " + System.getProperty("java.version")}
        );
    }

    /**
     * Return hostname without throwing exception.
     *
     * @return hostname
     */
    private static String getHostname() {
        try {
            return "" + InetAddress.getLocalHost();
        } catch (UnknownHostException uhe) {
            return "" + uhe;
        }
    }
}

VersionInfo类

package com.hyr;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/*******************************************************************************
 * @date 2018-12-04 上午 9:53
 * @author: <a href=mailto:>黄跃然</a>
 * @Description:
 ******************************************************************************/
public class BrowserVersionInfo {

    private static Logger LOG = LoggerFactory.getLogger(BrowserVersionInfo.class.getName());

    private static String VERSION = "version:";
    private static String DATATIME = "datetime:";
    private static String SVNVERSION = "svn-version:";

    private static String versionInfo;

    private static String version_str = "";
    private static String date_time_str = "";
    private static String svn_version_str = "";

    private static boolean isInit = false;

    static {
        try {
            versionInfo = getVersionInfo();

            if (versionInfo != null) {
                versionInfo = versionInfo.replace(" ", "");
                versionInfo = versionInfo.replaceAll("\n", "");
                Pattern version = Pattern.compile(VERSION);
                Pattern datetime = Pattern.compile(DATATIME);
                Pattern svn_version = Pattern.compile(SVNVERSION);
                Matcher version_matcher = version.matcher(versionInfo);
                Matcher datetime_matcher = datetime.matcher(versionInfo);
                Matcher svn_version_matcher = svn_version.matcher(versionInfo);

                if (version_matcher.find() && datetime_matcher.find() && svn_version_matcher.find()) {
                    version_str = versionInfo.substring(version_matcher.end(), datetime_matcher.start());
                    date_time_str = versionInfo.substring(datetime_matcher.end(), svn_version_matcher.start());
                    svn_version_str = versionInfo.substring(svn_version_matcher.end());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * get browser version
     *
     * @return
     */
    public static String getProjectVersion() {
        return !version_str.isEmpty() ? version_str : "Unknown";
    }

    /**
     * get compiled time
     *
     * @return
     */
    public static String getCompiledTime() {
        return !date_time_str.isEmpty() ? date_time_str : "Unknown";
    }

    /**
     * Get the subversion revision number for the root directory
     *
     * @return the revision number, eg. "451451"
     */
    public static String getSVNVersion() {
        return !svn_version_str.isEmpty() ? svn_version_str : "Unknown";
    }

    public static void main(String[] args) throws IOException {
        if (versionInfo != null) {
            versionInfo = versionInfo.replace(" ", "");
            System.out.println(versionInfo);
            Pattern version = Pattern.compile(VERSION);
            Pattern datetime = Pattern.compile(DATATIME);
            Pattern svn_version = Pattern.compile(SVNVERSION);
            Matcher version_matcher = version.matcher(versionInfo);
            Matcher datetime_matcher = datetime.matcher(versionInfo);
            Matcher svn_version_matcher = svn_version.matcher(versionInfo);

            if (version_matcher.find()) {
                System.out.println(version_matcher);
            }

            if (datetime_matcher.find()) {
                System.out.println(datetime_matcher);
            }

            if (svn_version_matcher.find()) {
                System.out.println(svn_version_matcher);
            }

            String version_str = versionInfo.substring(version_matcher.end(), datetime_matcher.start());

            String date_time_str = versionInfo.substring(datetime_matcher.end(), svn_version_matcher.start());

            String svn_version_str = versionInfo.substring(svn_version_matcher.end());
        }

    }

    private static String getVersionInfo() throws IOException {
        URL sourcePath = Main.class.getProtectionDomain().getCodeSource().getLocation();
        ZipFile zipFile = new ZipFile(sourcePath.getPath());
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        for (; entries.hasMoreElements(); ) {
            ZipEntry zipEntry = entries.nextElement();
            String filename = zipEntry.getName();
            if (filename.startsWith("ver_") && filename.endsWith(".txt")) {
                InputStream resourceAsStream = BrowserVersionInfo.class.getClassLoader().getResourceAsStream(filename);
                return IOUtils.toString(resourceAsStream);
            }
        }
        return null;
    }

    /**
     * 读取 InputStream 到 String字符串中
     */
    public static String readStream(InputStream in) {
        try {
            //<1>创建字节数组输出流,用来输出读取到的内容
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            //<2>创建缓存大小
            byte[] buffer = new byte[1024]; // 1KB
            //每次读取到内容的长度
            int len = -1;
            //<3>开始读取输入流中的内容
            while ((len = in.read(buffer)) != -1) { //当等于-1说明没有数据可以读取了
                baos.write(buffer, 0, len);   //把读取到的内容写到输出流中
            }
            //<4> 把字节数组转换为字符串
            String content = baos.toString();
            //<5>关闭输入流和输出流
            in.close();
            baos.close();
            //<6>返回字符串结果
            return content;
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

}

MAVEN依赖

注:部分JDK不支持javafx,如果需要引用上面的javafx.runtime.VersionInfo功能。需要单独引入javafx的依赖包。

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <scope>provided</scope>
        </dependency>

 

新增package-info实现,可以参考github项目。

Github地址: https://github.com/huangyueranbbc/StartUpShutDownMessageUtils 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值