running Docker-Compose
This commit is contained in:
11
spring-cloud/tracing/README.md
Normal file
11
spring-cloud/tracing/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Log Tracing with Spring Cloud Sleuth
|
||||
|
||||
This project shows how to implement tracing in a network of Spring Boot applications.
|
||||
|
||||
## Companion Blog Article
|
||||
The companion blog article to this repository can be found [here](https://reflectoring.io/tracing-with-spring-cloud-sleuth/).
|
||||
|
||||
## Getting Started
|
||||
|
||||
* build the sources with `./gradlew clean build` (don't forge to also do this after every change to the code, otherwise Docker will start the old image)
|
||||
* run the applications in Docker with `docker-compose up --build`
|
||||
@@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.5.6'
|
||||
id 'org.springframework.boot' version '2.5.6' apply(false) // we don't want the root project to be a Spring Boot project
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
id 'java'
|
||||
}
|
||||
@@ -14,14 +14,6 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
bootJar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
||||
apply plugin: 'java'
|
||||
|
||||
15
spring-cloud/tracing/docker-compose.yml
Normal file
15
spring-cloud/tracing/docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
version: "3.5"
|
||||
|
||||
services:
|
||||
|
||||
downstream:
|
||||
build: ./downstream-service/
|
||||
image: downstream:latest
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
||||
upstream:
|
||||
build: ./upstream-service/
|
||||
image: upstream:latest
|
||||
ports:
|
||||
- "8081:8081"
|
||||
5
spring-cloud/tracing/downstream-service/Dockerfile
Normal file
5
spring-cloud/tracing/downstream-service/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM adoptopenjdk/openjdk11:alpine-jre
|
||||
ARG JAR_FILE=build/libs/*.jar
|
||||
COPY ${JAR_FILE} application.jar
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["java","-jar","/application.jar"]
|
||||
@@ -1,6 +1,14 @@
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
enabled = true
|
||||
mainClass.set('com.example.demo.DemoApplication')
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class AddressClient {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final String baseUrl;
|
||||
|
||||
public AddressClient(
|
||||
RestTemplate restTemplate,
|
||||
@Value("${addressClient.baseUrl}") String baseUrl) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
Address getAddressForCustomerId(long id) {
|
||||
return restTemplate.getForObject(String.format("%s/addresses/%d", baseUrl, id), Address.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class CustomerClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CustomerClient.class);
|
||||
private RestTemplate restTemplate;
|
||||
private String baseUrl;
|
||||
|
||||
public CustomerClient(
|
||||
RestTemplate restTemplate,
|
||||
@Value("${customerClient.baseUrl}") String baseUrl) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
Customer getCustomer(@PathVariable("id") long id){
|
||||
String url = String.format("%s/customers/%d", baseUrl, id);
|
||||
return restTemplate.getForObject(url, Customer.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Configuration
|
||||
public class RestConfiguration {
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
server.port: 8080
|
||||
|
||||
addressClient:
|
||||
baseUrl: http://upstream:8081
|
||||
|
||||
customerClient:
|
||||
baseUrl: http://upstream:8081
|
||||
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
application:
|
||||
name: downstream-service
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
|
||||
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
|
||||
|
||||
<!-- You can override this to have a custom pattern -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
|
||||
<!-- Appender to log to console -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!-- Minimum logging level to be presented in the console logs-->
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -6,5 +6,5 @@ pluginManagement {
|
||||
}
|
||||
}
|
||||
|
||||
include "sleuth-downstream-service"
|
||||
include "sleuth-upstream-service"
|
||||
include "downstream-service"
|
||||
include "upstream-service"
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@FeignClient(value = "addresses", path = "/addresses")
|
||||
public interface AddressClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, path = "/{id}")
|
||||
Address getAddressForCustomerId(@PathVariable("id") long id);
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@FeignClient(value = "customers", path = "/customers")
|
||||
public interface CustomerClient {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{id}")
|
||||
Customer getCustomer(@PathVariable("id") long id);
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import feign.Logger;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class FeignConfiguration {
|
||||
|
||||
@Bean
|
||||
public Logger.Level logLevel(){
|
||||
return Logger.Level.FULL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.CommonsRequestLoggingFilter;
|
||||
|
||||
@Configuration
|
||||
public class RequestLoggingFilterConfig {
|
||||
|
||||
@Bean
|
||||
public CommonsRequestLoggingFilter logFilter() {
|
||||
CommonsRequestLoggingFilter filter
|
||||
= new CommonsRequestLoggingFilter();
|
||||
filter.setIncludeHeaders(true);
|
||||
filter.setIncludeQueryString(true);
|
||||
filter.setIncludePayload(true);
|
||||
filter.setMaxPayloadLength(10000);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
server.port: 8080
|
||||
|
||||
customers:
|
||||
ribbon:
|
||||
eureka:
|
||||
enabled: false
|
||||
listOfServers: localhost:8081
|
||||
|
||||
addresses:
|
||||
ribbon:
|
||||
eureka:
|
||||
enabled: false
|
||||
listOfServers: localhost:8081
|
||||
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
@@ -1,2 +0,0 @@
|
||||
# this file is loaded by Spring Cloud before application.properties
|
||||
spring.application.name=sleuth-downstream-service
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
|
||||
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
|
||||
<!-- Example for logging into the build folder of your project -->
|
||||
<property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>
|
||||
|
||||
<!-- You can override this to have a custom pattern -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [${springAppName},%X{X-B3-TraceId:-}] %m%n"/>
|
||||
|
||||
<!-- Appender to log to console -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!-- Minimum logging level to be presented in the console logs-->
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Appender to log to file -->
|
||||
<appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_FILE}</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Appender to log to file in a JSON format -->
|
||||
<!--<appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
|
||||
<!--<file>${LOG_FILE}.json</file>-->
|
||||
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
|
||||
<!--<fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>-->
|
||||
<!--<maxHistory>7</maxHistory>-->
|
||||
<!--</rollingPolicy>-->
|
||||
<!--<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
|
||||
<!--<providers>-->
|
||||
<!--<timestamp>-->
|
||||
<!--<timeZone>UTC</timeZone>-->
|
||||
<!--</timestamp>-->
|
||||
<!--<pattern>-->
|
||||
<!--<pattern>-->
|
||||
<!--{-->
|
||||
<!--"severity": "%level",-->
|
||||
<!--"service": "${springAppName:-}",-->
|
||||
<!--"trace": "%X{X-B3-TraceId:-}",-->
|
||||
<!--"span": "%X{X-B3-SpanId:-}",-->
|
||||
<!--"parent": "%X{X-B3-ParentSpanId:-}",-->
|
||||
<!--"exportable": "%X{X-Span-Export:-}",-->
|
||||
<!--"pid": "${PID:-}",-->
|
||||
<!--"thread": "%thread",-->
|
||||
<!--"class": "%logger{40}",-->
|
||||
<!--"rest": "%message"-->
|
||||
<!--}-->
|
||||
<!--</pattern>-->
|
||||
<!--</pattern>-->
|
||||
<!--</providers>-->
|
||||
<!--</encoder>-->
|
||||
<!--</appender>-->
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<!-- uncomment this to have also JSON logs -->
|
||||
<!--<appender-ref ref="logstash"/>-->
|
||||
<appender-ref ref="flatfile"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.CommonsRequestLoggingFilter;
|
||||
|
||||
@Configuration
|
||||
public class RequestLoggingFilterConfig {
|
||||
|
||||
@Bean
|
||||
public CommonsRequestLoggingFilter logFilter() {
|
||||
CommonsRequestLoggingFilter filter
|
||||
= new CommonsRequestLoggingFilter();
|
||||
filter.setIncludeHeaders(true);
|
||||
filter.setIncludeQueryString(true);
|
||||
filter.setIncludePayload(true);
|
||||
filter.setMaxPayloadLength(10000);
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter: DEBUG
|
||||
|
||||
server.port: 8081
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
@@ -1,2 +0,0 @@
|
||||
# this file is loaded by Spring Cloud before application.properties
|
||||
spring.application.name=sleuth-upstream-service
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
|
||||
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
|
||||
<!-- Example for logging into the build folder of your project -->
|
||||
<property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>
|
||||
|
||||
<!-- You can override this to have a custom pattern -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [${springAppName},%X{X-B3-TraceId:-}] %m%n"/>
|
||||
|
||||
<!-- Appender to log to console -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!-- Minimum logging level to be presented in the console logs-->
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Appender to log to file -->
|
||||
<appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_FILE}</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
|
||||
<maxHistory>7</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Appender to log to file in a JSON format -->
|
||||
<!--<appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
|
||||
<!--<file>${LOG_FILE}.json</file>-->
|
||||
<!--<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
|
||||
<!--<fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>-->
|
||||
<!--<maxHistory>7</maxHistory>-->
|
||||
<!--</rollingPolicy>-->
|
||||
<!--<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
|
||||
<!--<providers>-->
|
||||
<!--<timestamp>-->
|
||||
<!--<timeZone>UTC</timeZone>-->
|
||||
<!--</timestamp>-->
|
||||
<!--<pattern>-->
|
||||
<!--<pattern>-->
|
||||
<!--{-->
|
||||
<!--"severity": "%level",-->
|
||||
<!--"service": "${springAppName:-}",-->
|
||||
<!--"trace": "%X{X-B3-TraceId:-}",-->
|
||||
<!--"span": "%X{X-B3-SpanId:-}",-->
|
||||
<!--"parent": "%X{X-B3-ParentSpanId:-}",-->
|
||||
<!--"exportable": "%X{X-Span-Export:-}",-->
|
||||
<!--"pid": "${PID:-}",-->
|
||||
<!--"thread": "%thread",-->
|
||||
<!--"class": "%logger{40}",-->
|
||||
<!--"rest": "%message"-->
|
||||
<!--}-->
|
||||
<!--</pattern>-->
|
||||
<!--</pattern>-->
|
||||
<!--</providers>-->
|
||||
<!--</encoder>-->
|
||||
<!--</appender>-->
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<!-- uncomment this to have also JSON logs -->
|
||||
<!--<appender-ref ref="logstash"/>-->
|
||||
<appender-ref ref="flatfile"/>
|
||||
</root>
|
||||
</configuration>
|
||||
5
spring-cloud/tracing/upstream-service/Dockerfile
Normal file
5
spring-cloud/tracing/upstream-service/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM adoptopenjdk/openjdk11:alpine-jre
|
||||
ARG JAR_FILE=build/libs/*.jar
|
||||
COPY ${JAR_FILE} application.jar
|
||||
EXPOSE 8081
|
||||
ENTRYPOINT ["java","-jar","/application.jar"]
|
||||
@@ -2,4 +2,13 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
bootJar {
|
||||
enabled = true
|
||||
mainClass.set('com.example.demo.DemoApplication')
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
@@ -2,10 +2,8 @@ package com.example.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableFeignClients
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
@@ -0,0 +1,8 @@
|
||||
server.port: 8081
|
||||
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
application:
|
||||
name: upstream-service
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
|
||||
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
|
||||
|
||||
<!-- Appender to log to console -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}</pattern>
|
||||
<charset>utf8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user