added error handling and READMEs
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
# Log Tracing with Spring Cloud Sleuth
|
||||
|
||||
TBD
|
||||
This project shows how to implement tracing in a network of Spring Boot applications.
|
||||
|
||||
This application is a service facing the user (a "downstream" service), meaning that
|
||||
it accesses other upstream services to provide its functionality.
|
||||
|
||||
1. Start the [upstream service](../sleuth-upstream-service/) with `./gradlew bootrun`
|
||||
1. Start this service with `./gradlew bootrun`
|
||||
1. Open `http://localhost:8080/customers-with-address/{id}` where IDs from 1-50 are
|
||||
will return a valid HTTP 200 response and other IDs will return an error response.
|
||||
1. Look into the log files of both services and verify that both contain the same
|
||||
trace id.
|
||||
|
||||
@@ -29,6 +29,7 @@ ext {
|
||||
dependencies {
|
||||
compile('org.springframework.cloud:spring-cloud-starter-feign')
|
||||
compile('org.springframework.cloud:spring-cloud-starter-sleuth')
|
||||
compile('org.springframework.cloud:spring-cloud-starter-zipkin')
|
||||
compile('org.springframework.boot:spring-boot-starter-web')
|
||||
testCompile('org.springframework.boot:spring-boot-starter-test')
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class Controller {
|
||||
|
||||
@GetMapping(path = "customers-with-address/{id}")
|
||||
public CustomerAndAddress getCustomerWithAddress(@PathVariable("id") long customerId){
|
||||
logger.info("COLLECTING CUSTOMER AND ADDRESS WITH ID {} FROM SECONDARY SERVICE", customerId);
|
||||
logger.info("COLLECTING CUSTOMER AND ADDRESS WITH ID {} FROM UPSTREAM SERVICE", customerId);
|
||||
Customer customer = customerClient.getCustomer(customerId);
|
||||
Address address = addressClient.getAddressForCustomerId(customerId);
|
||||
return new CustomerAndAddress(customer, address);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ControllerAdvice
|
||||
public class ErrorHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ErrorHandler.class);
|
||||
|
||||
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public String handleInternalError(Exception e) {
|
||||
logger.error("internal server error", e);
|
||||
return String.format("Internal Server Error (traceId: %s)", MDC.get("X-B3-TraceId"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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,8 +1,6 @@
|
||||
server.port: 8080
|
||||
|
||||
logging.level.com.example.demo.CustomerClient: DEBUG
|
||||
logging.level.com.example.demo.AddressClient: DEBUG
|
||||
logging.level.org.hibernate.SQL: DEBUG
|
||||
spring.zipkin.baseUrl: http://localhost:9411/
|
||||
|
||||
customers:
|
||||
ribbon:
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# this file is loaded by Spring Cloud before application.properties
|
||||
spring.application.name=sleuth-primary-service
|
||||
spring.application.name=sleuth-downstream-service
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<!-- 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:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
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">
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
public class Address {
|
||||
|
||||
private long id;
|
||||
|
||||
private String street;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
public class Customer {
|
||||
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -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,3 +1,13 @@
|
||||
# Log Tracing with Spring Cloud Sleuth
|
||||
|
||||
TBD
|
||||
This project shows how to implement tracing in a network of Spring Boot applications.
|
||||
|
||||
This application is a service that's not facing the user (a "downstream" service), meaning that
|
||||
it is accessed by user-facing services so they can provide their functionality.
|
||||
|
||||
1. Start this service with `./gradlew bootrun`
|
||||
1. Start the [downstream service](../sleuth-downstream-service/) with `./gradlew bootrun`
|
||||
1. Open `http://localhost:8080/customers-with-address/{id}` where IDs from 1-50 are
|
||||
will return a valid HTTP 200 response and other IDs will return an error response.
|
||||
1. Look into the log files of both services and verify that both contain the same
|
||||
trace id.
|
||||
|
||||
@@ -28,6 +28,7 @@ ext {
|
||||
|
||||
dependencies {
|
||||
compile('org.springframework.cloud:spring-cloud-starter-sleuth')
|
||||
compile('org.springframework.cloud:spring-cloud-starter-zipkin')
|
||||
compile('org.springframework.boot:spring-boot-starter-web')
|
||||
testCompile('org.springframework.boot:spring-boot-starter-test')
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ControllerAdvice
|
||||
public class ErrorHandler {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ErrorHandler.class);
|
||||
|
||||
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public String handleInternalError(Exception e) {
|
||||
logger.error("internal server error", e);
|
||||
return String.format("Internal Server Error (traceId: %s)", MDC.get("X-B3-TraceId"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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,3 +1,7 @@
|
||||
logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter: DEBUG
|
||||
|
||||
spring.zipkin.baseUrl: http://localhost:9411/
|
||||
|
||||
server.port: 8081
|
||||
spring:
|
||||
output:
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# this file is loaded by Spring Cloud before application.properties
|
||||
spring.application.name=sleuth-secondary-service
|
||||
spring.application.name=sleuth-upstream-service
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<!-- 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:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] ${PID:- } --- [%15.15t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
|
||||
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">
|
||||
|
||||
Reference in New Issue
Block a user