60 lines
23 KiB
HTML
60 lines
23 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>157. Stackdriver Logging</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud.html" title="Spring Cloud"><link rel="up" href="multi_spring-cloud-gcp-reference.html" title="Part XVIII. Spring Cloud GCP"><link rel="prev" href="multi__spring_cloud_sleuth_2.html" title="156. Spring Cloud Sleuth"><link rel="next" href="multi__spring_cloud_config_2.html" title="158. Spring Cloud Config"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">157. Stackdriver Logging</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__spring_cloud_sleuth_2.html">Prev</a> </td><th width="60%" align="center">Part XVIII. Spring Cloud GCP</th><td width="20%" align="right"> <a accesskey="n" href="multi__spring_cloud_config_2.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h2 class="title"><a name="_stackdriver_logging" href="#_stackdriver_logging"></a>157. Stackdriver Logging</h2></div></div></div><p>Maven coordinates, using Spring Cloud GCP BOM:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-gcp-starter-logging<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p>Gradle coordinates:</p><pre class="screen">dependencies {
|
|
compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-logging'
|
|
}</pre><p><a class="link" href="https://cloud.google.com/logging/" target="_top">Stackdriver Logging</a> is the managed logging service provided by Google Cloud Platform.</p><p>This module provides support for associating a web request trace ID with the corresponding log entries.
|
|
It does so by retrieving the <code class="literal">X-B3-TraceId</code> value from the <a class="link" href="https://logback.qos.ch/manual/mdc.html" target="_top">Mapped Diagnostic Context (MDC)</a>, which is set by Spring Cloud Sleuth.
|
|
If Spring Cloud Sleuth isn’t used, the configured <code class="literal">TraceIdExtractor</code> extracts the desired header value and sets it as the log entry’s trace ID.
|
|
This allows grouping of log messages by request, for example, in the <a class="link" href="https://console.cloud.google.com/logs/viewer" target="_top">Google Cloud Console Logs viewer</a>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Due to the way logging is set up, the GCP project ID and credentials defined in <code class="literal">application.properties</code> are ignored.
|
|
Instead, you should set the <code class="literal">GOOGLE_CLOUD_PROJECT</code> and <code class="literal">GOOGLE_APPLICATION_CREDENTIALS</code> environment variables to the project ID and credentials private key location, respectively.
|
|
You can do this easily if you’re using the <a class="link" href="http://cloud.google.com/sdk" target="_top">Google Cloud SDK</a>, using the <code class="literal">gcloud config set project [YOUR_PROJECT_ID]</code> and <code class="literal">gcloud auth application-default login</code> commands, respectively.</p></td></tr></table></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_web_mvc_interceptor" href="#_web_mvc_interceptor"></a>157.1 Web MVC Interceptor</h2></div></div></div><p>For use in Web MVC-based applications, <code class="literal">TraceIdLoggingWebMvcInterceptor</code> is provided that extracts the request trace ID from an HTTP request using a <code class="literal">TraceIdExtractor</code> and stores it in a thread-local, which can then be used in a logging appender to add the trace ID metadata to log messages.</p><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Warning"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="images/warning.png"></td><th align="left">Warning</th></tr><tr><td align="left" valign="top"><p>If Spring Cloud GCP Trace is enabled, the logging module disables itself and delegates log correlation to Spring Cloud Sleuth.</p></td></tr></table></div><p><code class="literal">LoggingWebMvcConfigurer</code> configuration class is also provided to help register the <code class="literal">TraceIdLoggingWebMvcInterceptor</code> in Spring MVC applications.</p><p>Applications hosted on the Google Cloud Platform include trace IDs under the <code class="literal">x-cloud-trace-context</code> header, which will be included in log entries.
|
|
However, if Sleuth is used the trace ID will be picked up from the MDC.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_logback_support" href="#_logback_support"></a>157.2 Logback Support</h2></div></div></div><p>Currently, only Logback is supported and there are 2 possibilities to log to Stackdriver via this library with Logback: via direct API calls and through JSON-formatted console logs.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_log_via_api" href="#_log_via_api"></a>157.2.1 Log via API</h3></div></div></div><p>A Stackdriver appender is available using <code class="literal">org/springframework/cloud/gcp/autoconfigure/logging/logback-appender.xml</code>.
|
|
This appender builds a Stackdriver Logging log entry from a JUL or Logback log entry, adds a trace ID to it and sends it to Stackdriver Logging.</p><p><code class="literal">STACKDRIVER_LOG_NAME</code> and <code class="literal">STACKDRIVER_LOG_FLUSH_LEVEL</code> environment variables can be used to customize the <code class="literal">STACKDRIVER</code> appender.</p><p>Your configuration may then look like this:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">resource</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"org/springframework/cloud/gcp/autoconfigure/logging/logback-appender.xml"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /></span>
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><root</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">level</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"INFO"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><appender-ref</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">ref</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"STACKDRIVER"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></root></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span></pre><p>If you want to have more control over the log output, you can further configure the appender.
|
|
The following properties are available:</p><div class="informaltable"><table style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col class="col_1"><col class="col_2"><col class="col_3"></colgroup><thead><tr><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">Property</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">Default Value</th><th style="border-bottom: 0.5pt solid ; " align="left" valign="top">Description</th></tr></thead><tbody><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">log</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">spring.log</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>The Stackdriver Log name.
|
|
This can also be set via the <code class="literal">STACKDRIVER_LOG_NAME</code> environmental variable.</p></td></tr><tr><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">flushLevel</code></p></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">WARN</code></p></td><td style="" align="left" valign="top"><p>If a log entry with this level is encountered, trigger a flush of locally buffered log to Stackdriver Logging.
|
|
This can also be set via the <code class="literal">STACKDRIVER_LOG_FLUSH_LEVEL</code> environmental variable.</p></td></tr></tbody></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_log_via_console" href="#_log_via_console"></a>157.2.2 Log via Console</h3></div></div></div><p>For Logback, a <code class="literal">org/springframework/cloud/gcp/autoconfigure/logging/logback-json-appender.xml</code> file is made available for import to make it easier to configure the JSON Logback appender.</p><p>Your configuration may then look something like this:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">resource</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"org/springframework/cloud/gcp/autoconfigure/logging/logback-json-appender.xml"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /></span>
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><root</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">level</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"INFO"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><appender-ref</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">ref</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"CONSOLE_JSON"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"> /></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></root></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span></pre><p>If your application is running on Google Kubernetes Engine, Google Compute Engine or Google App Engine Flexible, your console logging is automatically saved to Google Stackdriver Logging.
|
|
Therefore, you can just include <code class="literal">org/springframework/cloud/gcp/autoconfigure/logging/logback-json-appender.xml</code> in your logging configuration, which logs JSON entries to the console.
|
|
The trace id will be set correctly.</p><p>If you want to have more control over the log output, you can further configure the appender.
|
|
The following properties are available:</p><div class="informaltable"><table style="border-collapse: collapse;border-top: 0.5pt solid ; border-bottom: 0.5pt solid ; "><colgroup><col class="col_1"><col class="col_2"><col class="col_3"></colgroup><thead><tr><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">Property</th><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top">Default Value</th><th style="border-bottom: 0.5pt solid ; " align="left" valign="top">Description</th></tr></thead><tbody><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">projectId</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p>If not set, default value is determined in the following order:</p>
|
|
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><code class="literal">SPRING_CLOUD_GCP_LOGGING_PROJECT_ID</code> Environmental Variable.</li><li class="listitem">Value of <code class="literal">DefaultGcpProjectIdProvider.getProjectId()</code></li></ol></div></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>This is used to generate fully qualified Stackdriver Trace ID format: <code class="literal">projects/[PROJECT-ID]/traces/[TRACE-ID]</code>.</p>
|
|
<p>This format is required to correlate trace between Stackdriver Trace and Stackdriver Logging.</p>
|
|
<p>If <code class="literal">projectId</code> is not set and cannot be determined, then it’ll log <code class="literal">traceId</code> without the fully qualified format.</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeTraceId</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the <code class="literal">traceId</code> be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeSpanId</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the <code class="literal">spanId</code> be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeLevel</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the severity be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeThreadName</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the thread name be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeMDC</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should all MDC properties be included.
|
|
The MDC properties <code class="literal">X-B3-TraceId</code>, <code class="literal">X-B3-SpanId</code> and <code class="literal">X-Span-Export</code> provided by Spring Sleuth will get excluded as they get handled separately</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeLoggerName</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the name of the logger be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeFormattedMessage</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the formatted log message be included.</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeExceptionInMessage</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the stacktrace be appended to the formatted log message.
|
|
This setting is only evaluated if <code class="literal">includeFormattedMessage</code> is <code class="literal">true</code></p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeContextName</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">true</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the logging context be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeMessage</code></p></td><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">false</code></p></td><td style="border-bottom: 0.5pt solid ; " align="left" valign="top"><p>Should the log message with blank placeholders be included</p></td></tr><tr><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">includeException</code></p></td><td style="border-right: 0.5pt solid ; " align="left" valign="top"><p><code class="literal">false</code></p></td><td style="" align="left" valign="top"><p>Should the stacktrace be included as a own field</p></td></tr></tbody></table></div><p>This is an example of such an Logback configuration:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration ></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><property</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">name</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"projectId"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">value</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"${projectId:-${GOOGLE_CLOUD_PROJECT}}"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">/></span>
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><appender</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">name</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"CONSOLE_JSON"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">class</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"ch.qos.logback.core.ConsoleAppender"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><encoder</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">class</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"ch.qos.logback.core.encoder.LayoutWrappingEncoder"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><layout</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">class</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"org.springframework.cloud.gcp.logging.StackdriverJsonLayout"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><projectId></span>${projectId}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></projectId></span>
|
|
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeTraceId>true</includeTraceId>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeSpanId>true</includeSpanId>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeLevel>true</includeLevel>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeThreadName>true</includeThreadName>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeMDC>true</includeMDC>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeLoggerName>true</includeLoggerName>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeFormattedMessage>true</includeFormattedMessage>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeExceptionInMessage>true</includeExceptionInMessage>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeContextName>true</includeContextName>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeMessage>false</includeMessage>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<includeException>false</includeException>--></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></layout></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></encoder></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></appender></span>
|
|
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span></pre></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_sample_7" href="#_sample_7"></a>157.3 Sample</h2></div></div></div><p>A <a class="link" href="https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-samples/spring-cloud-gcp-logging-sample" target="_top">Sample Spring Boot Application</a> is provided to show how to use the Cloud logging starter.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__spring_cloud_sleuth_2.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="multi_spring-cloud-gcp-reference.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multi__spring_cloud_config_2.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">156. Spring Cloud Sleuth </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud.html">Home</a></td><td width="40%" align="right" valign="top"> 158. Spring Cloud Config</td></tr></table></div></body></html> |