All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sviolet.thistle.x.util.trace.Trace Maven / Gradle / Ivy

There is a newer version: 22.1.0
Show newest version
/*
 * Copyright (C) 2015-2019 S.Violet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project GitHub: https://github.com/shepherdviolet/thistle
 * Email: [email protected]
 */

package sviolet.thistle.x.util.trace;

import com.github.shepherdviolet.glaciion.Glaciion;

import java.util.Map;
import java.util.concurrent.Callable;

/**
 * 全局追踪API, Glaciion扩展点: sviolet.thistle.x.util.trace.TraceProvider.
 * 默认实现: DefaultTraceProvider.
 *
 * @author S.Violet
 */
public class Trace {

    public static final String TRACE_ID_KEY = "_trace_id_";

    private static final TraceProvider PROVIDER = Glaciion.loadSingleService(TraceProvider.class).get();

    /**
     * 重头开始追踪
     */
    public static void start(){
        PROVIDER.start();
    }

    /**
     * 重新开始追踪
     * @param customTraceId 指定新的追踪号
     */
    public static void start(String customTraceId){
        PROVIDER.start(customTraceId);
    }

    /**
     * 继续追踪
     * @param traceBaton 追踪接力信息, 如果送空则从头开始
     */
    public static void handoff(TraceBaton traceBaton){
        if (traceBaton == null) {
            PROVIDER.start();
        } else {
            PROVIDER.handoff(traceBaton.getTraceId(), traceBaton.getTraceData());
        }
    }

    /**
     * 创建一个可追踪的Runnable(自动完成接力), 用于异步追踪
     * @param runnable Runnable
     * @return 可追踪的Runnable(自动完成接力), 用于异步追踪
     */
    public static Runnable traceable(Runnable runnable){
        return new TraceableRunnable(runnable);
    }

    /**
     * 创建一个可追踪的Callable(自动完成接力), 用于异步追踪
     * @param callable Callable
     * @return 可追踪的Callable(自动完成接力), 用于异步追踪
     */
    public static  Callable traceable(Callable callable){
        return new TraceableCallable<>(callable);
    }

    /**
     * 获取追踪接力信息
     */
    public static TraceBaton getBaton(){
        return new TraceBaton(getTraceId(), getDataMap());
    }

    /**
     * 获取追踪号
     */
    public static String getTraceId(){
        String traceId = PROVIDER.getTraceId();
        if (traceId == null) {
            PROVIDER.start();
            traceId = PROVIDER.getTraceId();
        }
        return traceId;
    }

    /**
     * 获取其他追踪信息
     */
    public static String getData(String key){
        return PROVIDER.getTraceData().get(key);
    }

    /**
     * 获取其他追踪信息
     *
     * @param fallback 如果取不到则返回该值
     */
    public static String getData(String key, String fallback) {
        String result = PROVIDER.getTraceData().get(key);
        return result != null ? result : fallback;
    }

    /**
     * 设置其他追踪信息
     */
    public static String setData(String key, String value) {
        return PROVIDER.getTraceData().put(key, value);
    }

    /**
     * 获取所有其他追踪信息
     */
    public static Map getDataMap(){
        return PROVIDER.getTraceData();
    }

    /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


    private static class TraceableCallable implements Callable {

        private Callable callable;
        private TraceBaton traceBaton;

        private TraceableCallable(Callable callable) {
            this.callable = callable;
            //获取接力信息
            traceBaton = Trace.getBaton();
        }

        @Override
        public T call() throws Exception {
            //接力
            Trace.handoff(traceBaton);
            return callable.call();
        }

    }

    private static class TraceableRunnable implements Runnable {

        private Runnable runnable;
        private TraceBaton traceBaton;

        private TraceableRunnable(Runnable runnable) {
            this.runnable = runnable;
            //获取接力信息
            traceBaton = Trace.getBaton();
        }

        @Override
        public final void run() {
            //接力
            Trace.handoff(traceBaton);
            runnable.run();
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy