As the question, maybe some people feel that doing this is a bit unnecessary, but personally feel the necessity of this is still some. For nothing but to save a few seconds of search time. Overall, there will be some minor improvements in the development and debugging of micro-services, which is also a kind of optimization for convenient development partners. A good framework is optimized bit by bit. No more nonsense, talk about the general idea and finally give a realization. We need to get the SkyWalking service address and traceId. The idea is that these two steps seem simple
Show your code Maven dependencies. Please feel free to use the header
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>omsa-all</artifactId>
<groupId>com.qimo</groupId>
<version>0.0.1 - the SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.qimo.trace</groupId>
<artifactId>omsa-trace</artifactId>
<packaging>jar</packaging>
<dependencies>
<! -- trace related packages -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.2.0</version>
</dependency>
<! -- Trace and Logback integrated package -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5. RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.3. RELEASE</version>
</dependency>
<! -- Config prompt generate package -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.1.3. RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
Copy the code
Define the address skywalkingUrl for the attribute oap_UI
package com.qimo.trace;
import org.springframework.boot.context.properties.ConfigurationProperties;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/20 struck * /
@ConfigurationProperties(prefix = "omsa.trace")
public class OmsaTraceProperties {
private String skywalkingUrl="http://";
public String getSkywalkingUrl(a) {
return skywalkingUrl;
}
public void setSkywalkingUrl(String skywalkingUrl) {
this.skywalkingUrl = skywalkingUrl; }}Copy the code
Define interceptor to head plug traceId and skywalkingUrl splicing the address of the final effect is http://127.0.0.1:10800/trace? TraceId = 0 a0cb455e8bf44718a70589e5818d5f9. 66.16242401437190001
package com.qimo.trace;
import com.qimo.trace.configuration.OmsaTraceConst;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/20 declare * /
public class OmsaTraceHeaderInterceptor extends HandlerInterceptorAdapter {
@Autowired
OmsaTraceProperties omsaTraceProperties;
public OmsaTraceHeaderInterceptor(a) {
super(a); }@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String traceId=TraceContext.traceId();
if (StringUtils.isEmpty(traceId)){
traceId=OmsaTraceConst.NULL_TRACE_ID;
}
response.setHeader(OmsaTraceConst.OMSA_TRACE_VISIT_URL_KEY, omsaTraceProperties.getSkywalkingUrl().replace("@{traceId}",traceId));
return true; }}Copy the code
We use @enable * to load the function of the package
package com.qimo.trace.annotation;
import com.qimo.trace.OmsaTraceProperties;
import com.qimo.trace.configuration.OmsaTraceConfigurationImportSelector;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/21 0:20 * /
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableOmsaTrace {
String[] includePatterns() default {"/ / * * * *"};
String[] excludePatterns() default {"/**/*.js"."/**/*.css"."/**/*.html"};
}
Copy the code
Write the Registrar configuration Bean
package com.qimo.trace.configuration;
import com.qimo.trace.annotation.EnableOmsaTrace;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.web.servlet.handler.MappedInterceptor;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/21 0:23 * /
public class OmsaTraceBeanRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
String[] includePatterns = getAnnotationAttributesValue(importingClassMetadata, "includePatterns");
String[] excludePatterns = getAnnotationAttributesValue(importingClassMetadata, "excludePatterns");
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MappedInterceptor.class);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(2.new RuntimeBeanReference(
OmsaTraceConst.OMSA_TRACE_HEADER_INTERCEPTOR_BEAN_NAME));
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
}
private String[] getAnnotationAttributesValue(AnnotationMetadata metadata, String attribute) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(EnableOmsaTrace.class.getName()));
String[] basePackages = attributes.getStringArray(attribute);
returnbasePackages; }}Copy the code
3. Write a Configuration bean
package com.qimo.trace.configuration;
import com.qimo.trace.OmsaTraceHeaderInterceptor;
import org.springframework.context.annotation.Bean;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/20 23:57 * /
public class OmsaTraceConfiguration {
@Bean(OmsaTraceConst.OMSA_TRACE_HEADER_INTERCEPTOR_BEAN_NAME)
public OmsaTraceHeaderInterceptor omsaTraceHeaderInterceptor(a){
return newOmsaTraceHeaderInterceptor(); }}Copy the code
Write selectort to collect beans that need to be loaded
package com.qimo.trace.configuration;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/21 0:22 * /
public class OmsaTraceConfigurationImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> importList=new ArrayList<String>();
importList.add(OmsaTraceConfiguration.class.getName());
importList.add(OmsaTraceBeanRegistrar.class.getName());
return importList.toArray(newString[importList.size()]); }}Copy the code
Modify annotations to import selector and Properties
package com.qimo.trace.annotation;
import com.qimo.trace.OmsaTraceProperties;
import com.qimo.trace.configuration.OmsaTraceConfigurationImportSelector;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/21 0:20 * /
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableConfigurationProperties(OmsaTraceProperties.class)
@Import(OmsaTraceConfigurationImportSelector.class)
@Documented
public @interface EnableOmsaTrace {
String[] includePatterns() default {"/ / * * * *"};
String[] excludePatterns() default {"/**/*.js"."/**/*.css"."/**/*.html"};
}
Copy the code
Of course, at the same time you also need to have skyWalking server and agent, it is very simple to pull one directly from dockerHub, the version of the above package is 8.2.0, I directly pull a 8.2.0 server, directly use docker-compose.
version: "3.1"
services:
oap:
image: Apache/skywalking - oap - server: 8.2.0 - es7
restart: always
ports:
- 11800: 11800
- 12800: 12800
oap_ui:
image: Apache/skywalking - UI: 8.2.0
restart: always
environment:
SW_OAP_ADDRESS: "oap:12800"
ports:
- 10800: 8080
Copy the code
Introduce the current package again with a Springboot-demo project. Try annotating @enableomsatrace on the startup class
@SpringBootApplication
@EnableOmsaTrace
public class OmsaDemoApplication {
public static void main(String[] args) {
SpringApplication.run(OmsaDemoApplication.class,args);
}
Copy the code
Of course, you need to configure logback because we only do logback here. If you want to use other logging frameworks, you need to replace the top layer of the dependency layer with the logback-spring configuration:
<configuration>
<jmxConfigurator/>
<property name="log_pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS Z} [%tid] [%thread] %-5level %logger{50}:%line %msg%n"></property>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<! - - - >
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<! -- Display format -->
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${log_pattern}</pattern>
</layout>
</encoder>
</appender>
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<! - - - >
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<! -- Display format -->
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${log_pattern}</pattern>
</layout>
</encoder>
<! -- Scroll Strategy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<! -- -- -- > path
<fileNamePattern>log/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<! -- Divide files over 100M -->
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
</appender>
<! -- Specify the most basic log output level -->
<root level="info">
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileLog"/>
</root>
</configuration>
Copy the code
I’ll write a simple controller
package com.qimo.omsa.demo.trace;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/ * * *@Description TODO
* @AuthorYao Zhongjie #80998699 *@Date2021/6/21 1:18 * /
@RestController
public class TraceTestController {
Logger log= LoggerFactory.getLogger(TraceTestController.class);
@GetMapping("/trace")
public String trace(a){
log.info(TraceContext.traceId());
returnTraceContext.traceId(); }}Copy the code
Your SkyWalking address on the application. Properties configuration
Server port = 7777 logging. Level. The root = info omsa. Trace. Skywalking - url = HTTP: / / http://127.0.0.1:10800/trace? traceId=@{traceId}Copy the code
The access effect is as followsCopy the link to access directly