Forked from pismy/HttpRequestHandlerWithMdcPropagation.java
Created
September 20, 2018 07:23
-
-
Save guozi/ce23d0425f699b5074502a6f2ce80fcc to your computer and use it in GitHub Desktop.
SLF4J & Apache Http tool: propagates MDC context over client Http requests (suitable for micro-services architecture)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import org.apache.http.HttpException; | |
import org.apache.http.HttpRequest; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.message.BasicHeader; | |
import org.apache.http.protocol.HttpContext; | |
import org.apache.http.protocol.HttpRequestHandler; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.slf4j.MDC; | |
/** | |
* Apache Http {@link HttpRequestHandler} that enables propagating part or all of the {@link MDC} context over Http requests | |
* <p> | |
* Requires SLF4J as the logging facade API and Apache Http as the client Http stack. | |
* <p> | |
* By default propagates {@code requestId} MDC attribute as {@code X-Track-RequestId} header but it can be overridden using the | |
* {@code slf4j.tools.propagate.mdc.fields} Java property formatted as: | |
* <pre class=code><mdc name 1>: <header name 1>, <mdc name 2>: <header name 2>, <mdc name 3>: <header name 3></pre> | |
* <p> | |
* Example: | |
* <pre class=code>requestId: X-Track-RequestId, sessionId: X-Track-SessionId, time: X-Track-Time</pre> | |
* | |
* @author pismy | |
* | |
*/ | |
public class HttpRequestHandlerWithMdcPropagation implements HttpRequestHandler { | |
private static final Logger LOGGER = LoggerFactory.getLogger(MdcPropagatorOverHttpRequests.class); | |
private final Map<String, String> mdcName2HeaderName; | |
public MdcPropagatorOverHttpRequests() { | |
mdcName2HeaderName = new HashMap<>(); | |
String mdcFieldsConfig = System.getProperty("slf4j.tools.propagate.mdc.fields", "requestId: X-Track-RequestId").trim(); | |
String[] mdcFields = mdcFieldsConfig.split(","); | |
for (String mdc2Header : mdcFields) { | |
int idx = mdc2Header.indexOf(':'); | |
if (idx <= 0) { | |
LOGGER.warn("Unexpected configuration format in '{}': items should be formatted as '<mdc name>: <header name>'", mdcFieldsConfig); | |
} else { | |
String mdc = mdc2Header.substring(0, idx).trim(); | |
String header = mdc2Header.substring(idx + 1).trim(); | |
if (mdc.isEmpty() || header.isEmpty()) { | |
LOGGER.warn("Unexpected configuration format in '{}': items should be formatted as '<mdc name>: <header name>'", mdcFieldsConfig); | |
} else { | |
mdcName2HeaderName.put(mdc, header); | |
} | |
} | |
} | |
} | |
@Override | |
public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { | |
for (Entry<String, String> e : mdcName2HeaderName.entrySet()) { | |
String mdcValue = MDC.get(e.getKey()); | |
if (mdcValue != null) { | |
request.addHeader(new BasicHeader(e.getValue(), mdcValue)); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment