Commit 85bf1ecb authored by 江洋洋's avatar 江洋洋

dsp

parent e1b35b0b
......@@ -38,7 +38,7 @@ allprojects {
}
group = "cn.com.duiba.boot"
version = "0.0.36"
version = "0.0.39-jyy-01-SNAPSHOT"
}
subprojects {
......
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.cloud:spring-cloud-starter-openfeign"
compile 'org.springframework.boot:spring-boot-autoconfigure'
compile "org.apache.dubbo:dubbo-spring-boot-starter"
compile "com.alibaba:transmittable-thread-local"
compile "org.apache.commons:commons-lang3"
compile 'cn.hutool:hutool-all:4.1.19'
provided('cn.com.duiba.tuia-pangea-center:pangea-center-api:0.0.51')
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.cloud.openfeign.FeignClient;
@Slf4j
@Configuration
@ConditionalOnClass({FeignClient.class})
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class DuibaRpcContextParamsInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String samplingId = request.getHeader(SamplerLogConstant.RPC_SAMPLING_ID);
if (StringUtils.isBlank(samplingId)) {
return true;
}
SamplerLog.setSamplerId(samplingId);
return true;
}
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
import cn.com.duiba.spring.boot.starter.dsp.sampler.constants.SamplerLogProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author jiangyangyang
* @version 1.0
* @description: 日志抽样开关
* @date 2022/3/4 上午10:50
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({SamplerLogAutoConfiguration.class})
@EnableConfigurationProperties(SamplerLogProperties.class)
public @interface EnableSamplerLog {
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
@ConditionalOnClass({FeignClient.class})
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Import(DuibaRpcContextParamsInterceptor.class)
public class RpcContextParamsInterceptorConfig {
@Bean
public InterceptorRegisterConfig interceptorRegister(){
return new InterceptorRegisterConfig();
}
static class InterceptorRegisterConfig implements WebMvcConfigurer, Ordered {
@Resource
private DuibaRpcContextParamsInterceptor interceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addPathPatterns("/**");
}
@Override
public int getOrder() {
return -100;
}
}
}
\ No newline at end of file
package cn.com.duiba.spring.boot.starter.dsp.sampler;
import cn.com.duiba.spring.boot.starter.dsp.sampler.constants.SamplerLogProperties;
import cn.com.duiba.spring.boot.starter.dsp.sampler.converter.SamplerLogConverter;
import cn.hutool.core.lang.UUID;
import com.alibaba.ttl.TransmittableThreadLocal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
@RefreshScope
public class SamplerLog {
private static final Logger logger = LoggerFactory.getLogger(SamplerLog.class);
......@@ -15,29 +22,51 @@ public class SamplerLog {
private static final Random random = new Random();
public static void start(Integer samplingRate){
if (random.nextInt(samplingRate) != 0) {
@Resource
private SamplerLogConverter samplerLogConverter;
@Resource
private SamplerLogProperties samplerLogProperties;
private static SamplerLog samplerLog;
/**
* 根据不同类型的业务需求对应的抽样比动态设置日志打印标识
*
* @param type 业务类型
* @param value 业务类型对应的值
*/
public static void start(String type, String value) {
if (infoFlag()) {
return;
}
LOCAL.set(UUID.randomUUID().toString());
Integer sampling = samplerLog.samplerLogConverter.getSampling(type, value);
sampling = sampling == null ? samplerLog.samplerLogProperties.getDefaultSize() : sampling;
if (random.nextInt(sampling) == 0) {
LOCAL.set(UUID.randomUUID().toString(true));
}
public static void end(){
LOCAL.remove();
}
public static String getSamplerId(){
return LOCAL.get();
/**
* 根据默认的抽样比设置日志打印标识
*/
public static void start() {
if (infoFlag()) {
return;
}
public static void setSamplerId(String samplerId) {
LOCAL.set(samplerId);
if (random.nextInt(samplerLog.samplerLogProperties.getDefaultSize()) == 0) {
LOCAL.set(UUID.randomUUID().toString(true));
}
public static boolean infoFlag() {
return Objects.nonNull(LOCAL.get());
}
/**
* info日志打印
*
* @param format
* @param arguments
*/
public static void info(String format, Object... arguments) {
try {
if (infoFlag()) {
......@@ -48,4 +77,39 @@ public class SamplerLog {
}
}
/**
* info日志是否全量打印
*
* @param fullFlag
* @param format
* @param arguments
*/
public static void info(boolean fullFlag, String format, Object... arguments) {
if (fullFlag) {
logger.info(format, arguments);
return;
}
info(format, arguments);
}
public static void end() {
LOCAL.remove();
}
public static String getSamplerId() {
return LOCAL.get();
}
public static void setSamplerId(String samplerId) {
LOCAL.set(samplerId);
}
public static boolean infoFlag() {
return Objects.nonNull(LOCAL.get());
}
@PostConstruct
public void init() {
samplerLog = this;
}
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
import cn.com.duiba.spring.boot.starter.dsp.sampler.converter.ApolloPanGuConverter;
import cn.com.duiba.spring.boot.starter.dsp.sampler.converter.SamplerLogConverter;
import cn.com.duiba.spring.boot.starter.dsp.sampler.feign.SamplerLogRequestInterceptor;
import cn.com.duiba.spring.boot.starter.dsp.sampler.filter.DubboLogSamplerContextFilter;
import cn.com.duiba.spring.boot.starter.dsp.sampler.filter.RpcLogSamplerContextFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
/**
* @author jiangyangyang
* @version 1.0
* @description: 抽样日志全部配置
* @date 2022/3/4 下午4:23
*/
public class SamplerLogAutoConfiguration {
//获取样本数默认实现,盘古实现
@Bean
@ConditionalOnMissingBean(SamplerLogConverter.class)
public ApolloPanGuConverter apolloPanGuConverter() {
return new ApolloPanGuConverter();
}
//feign调用拦截器,主要设置请求头
@Bean
public SamplerLogRequestInterceptor customRequestInterceptor() {
return new SamplerLogRequestInterceptor();
}
//dubbo服务调用过滤器,设置请求头和接收请求头
@Bean
public DubboLogSamplerContextFilter dubboLogSamplerContextFilter() {
return new DubboLogSamplerContextFilter();
}
//servlet过滤器
@Bean
public RpcLogSamplerContextFilter rpcLogSamplerContextFilter() {
return new RpcLogSamplerContextFilter();
}
//抽样日志打印核心工具类
@Bean
public SamplerLog samplerLog() {
return new SamplerLog();
}
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
package cn.com.duiba.spring.boot.starter.dsp.sampler.constants;
public class SamplerLogConstant {
//rpc调用请求头常量
public static String RPC_SAMPLING_ID = "rpcSamplingId";
//dubbo调用请求头常量
public static String DUBBO_SAMPLING_ID = "dubboSamplingId";
}
package cn.com.duiba.spring.boot.starter.dsp.sampler.constants;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
/**
* @author jiangyangyang
* @version 1.0
* @description:
* @date 2022/3/8 上午10:34
*/
@RefreshScope
@ConfigurationProperties("sampler.log")
public class SamplerLogProperties {
private Integer defaultSize = 500;
public Integer getDefaultSize() {
return defaultSize;
}
public void setDefaultSize(Integer defaultSize) {
this.defaultSize = defaultSize;
}
}
package cn.com.duiba.spring.boot.starter.dsp.sampler.converter;
import cn.com.duiba.tuia.pangea.center.api.localservice.apollopangu.ApolloPanGuService;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.Resource;
import java.util.Map;
/**
* @author jiangyangyang
* @version 1.0
* @description:
* @date 2022/3/4 下午2:30
*/
public class ApolloPanGuConverter implements SamplerLogConverter {
@Resource
private ApolloPanGuService apolloPanGuService;
@Value("${spring.application.name}")
private String applicationName;
/**
* 广告位:slot
* 媒体:app
* adx:adx
*
* @param type
* @param value
* @return
*/
public Integer getSampling(String type, String value) {
String panGuKey = applicationName + "_" + type;
Map<String, String> samplingMap = null;
try {
samplingMap = apolloPanGuService.getIdMapByKeyStr(panGuKey);
}catch (Exception e){
}
if (MapUtil.isEmpty(samplingMap)) {
return null;
}
String samplingStr = samplingMap.get(value);
if (StringUtils.isEmpty(samplingStr) || !NumberUtil.isNumber(samplingStr)) {
return null;
}
return Integer.parseInt(samplingStr);
}
}
package cn.com.duiba.spring.boot.starter.dsp.sampler.converter;
/**
* @author jiangyangyang
* @version 1.0
* @description: TODO
* @date 2022/3/4 下午3:40
*/
public interface SamplerLogConverter {
Integer getSampling(String type, String value);
}
package cn.com.duiba.spring.boot.starter.dsp.sampler;
package cn.com.duiba.spring.boot.starter.dsp.sampler.feign;
import cn.com.duiba.spring.boot.starter.dsp.sampler.SamplerLog;
import cn.com.duiba.spring.boot.starter.dsp.sampler.constants.SamplerLogConstant;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class CustomRequestInterceptor implements RequestInterceptor {
public class SamplerLogRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
......
package cn.com.duiba.spring.boot.starter.dsp.sampler;
package cn.com.duiba.spring.boot.starter.dsp.sampler.filter;
import lombok.extern.slf4j.Slf4j;
import cn.com.duiba.spring.boot.starter.dsp.sampler.SamplerLog;
import cn.com.duiba.spring.boot.starter.dsp.sampler.constants.SamplerLogConstant;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import java.util.Objects;
@Slf4j
@Activate(group = {CommonConstants.CONSUMER, CommonConstants.PROVIDER}, order = -2000)
public class DubboLogSamplerContextFilter implements Filter {
......@@ -30,7 +31,7 @@ public class DubboLogSamplerContextFilter implements Filter {
try {
return invoker.invoke(invocation);
} finally {
if (!isConsumerSide){
if (SamplerLog.infoFlag()){
SamplerLog.end();
}
}
......
package cn.com.duiba.spring.boot.starter.dsp.sampler.filter;
import cn.com.duiba.spring.boot.starter.dsp.sampler.SamplerLog;
import cn.com.duiba.spring.boot.starter.dsp.sampler.constants.SamplerLogConstant;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author jiangyangyang
* @version 1.0
* @description: rpc调用抽样日志过滤器
* @date 2022/3/4 上午10:55
*/
public class RpcLogSamplerContextFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String samplerId = httpServletRequest.getHeader(SamplerLogConstant.RPC_SAMPLING_ID);
if (StringUtils.isNotEmpty(samplerId)) {
SamplerLog.setSamplerId(samplerId);
}
try {
chain.doFilter(request, response);
} finally {
if (SamplerLog.infoFlag()) {
SamplerLog.end();
}
}
}
}
dubboLogSamplerContextFilter=cn.com.duiba.spring.boot.starter.dsp.sampler.DubboLogSamplerContextFilter
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.com.duiba.spring.boot.starter.dsp.sampler.RpcContextParamsInterceptorConfig
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment