Sync docs from master to gh-pages
18
antrun/build-main.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<project name="maven-antrun-" default="main" >
|
||||
<target name="main">
|
||||
<echo file="/Users/mgrzejszczak/repo/spring-cloud-sleuth/docs/target/spring-cloud-sleuth.adoc">:nofooter:
|
||||
:linkcss:
|
||||
:stylesdir: css
|
||||
:stylesheet: manual-singlepage.css
|
||||
|
||||
= {docs-main}
|
||||
|
||||
{spring-cloud-version}
|
||||
|
||||
== Pick The Documentation Option
|
||||
|
||||
- link:single/{docs-main}.html[Single HTML]
|
||||
- link:multi/{docs-main}.html[Multi HTML]</echo>
|
||||
</target>
|
||||
</project>
|
||||
2
checkstyle-cachefile
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tue Aug 29 10:25:58 CEST 2017
|
||||
configuration*?=AAF64E6F43093085564EA8A1303772CC40B65829
|
||||
20
checkstyle-checker.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<module name="TreeWalker">
|
||||
<!-- this. in front of fields -->
|
||||
<module name="RequireThis">
|
||||
<property name="checkMethods" value="false"/>
|
||||
</module>
|
||||
<!-- tabs instead of spaces -->
|
||||
<module name="RegexpSinglelineJava">
|
||||
<property name="format" value="^\t* "/>
|
||||
<property name="message" value="Indent must use tab characters"/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
</module>
|
||||
<module name="UnusedImports"/>
|
||||
<module name="RedundantImport"/>
|
||||
</module>
|
||||
</module>
|
||||
202
checkstyle-header.txt
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
3
checkstyle-result.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<checkstyle version="6.11.2">
|
||||
</checkstyle>
|
||||
35
css/highlight.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
code highlight CSS resemblign the Eclipse IDE default color schema
|
||||
@author Costin Leau
|
||||
*/
|
||||
|
||||
.hl-keyword {
|
||||
color: #7F0055;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hl-comment {
|
||||
color: #3F5F5F;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-multiline-comment {
|
||||
color: #3F5FBF;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-tag {
|
||||
color: #3F7F7F;
|
||||
}
|
||||
|
||||
.hl-attribute {
|
||||
color: #7F007F;
|
||||
}
|
||||
|
||||
.hl-value {
|
||||
color: #2A00FF;
|
||||
}
|
||||
|
||||
.hl-string {
|
||||
color: #2A00FF;
|
||||
}
|
||||
9
css/manual-multipage.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body.firstpage {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: none;
|
||||
}
|
||||
6
css/manual-singlepage.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
344
css/manual.css
Normal file
@@ -0,0 +1,344 @@
|
||||
@IMPORT url("highlight.css");
|
||||
|
||||
html {
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333333;
|
||||
margin: 15px 30px;
|
||||
font-family: Helvetica, Arial, Freesans, Clean, Sans-serif;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 16px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
:not(a)>code {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
:not(pre)>code {
|
||||
background-color: #F2F2F2;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px 0;
|
||||
text-shadow: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body>*:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #CCCCCC;
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000000;
|
||||
cursor: text;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1,h2,h3 {
|
||||
margin: 40px 0 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 70px 0 30px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: 1px dotted #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h1 code {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
h2,h2 code {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h3,h3 code {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h4,h1 code,h5,h5 code,h6,h6 code {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
div.book,div.chapter,div.appendix,div.part,div.preface {
|
||||
min-width: 300px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
p.releaseinfo {
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
div.authorgroup {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
p.copyright {
|
||||
line-height: 1;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
|
||||
.legalnotice p {
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.titlepage+p,div.titlepage+p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul,ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.table {
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.table table,div.informaltable table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.table td {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
line-height: 1.4;
|
||||
padding: 0 20px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
.sidebar p.title {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
pre.programlisting,pre.screen {
|
||||
font-size: 15px;
|
||||
padding: 6px 10px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
line-height: 1.4;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #DDDDDD !important;
|
||||
border-radius: 4px !important;
|
||||
border-collapse: separate !important;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
table thead {
|
||||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table th,table td {
|
||||
border: none !important;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
td p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
div.table-contents td p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist *
|
||||
{
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important p,div.note p,div.tip p,div.warning p {
|
||||
color: #6F6F6F;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
div.important code,div.note code,div.tip code,div.warning code {
|
||||
background-color: #F2F2F2 !important;
|
||||
border: 1px solid #CCCCCC !important;
|
||||
border-radius: 4px !important;
|
||||
padding: 1px 3px 0 !important;
|
||||
text-shadow: none !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.note th,.tip th,.warning th {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td
|
||||
{
|
||||
border-right: 1px solid #CCCCCC !important;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
div.calloutlist p,div.calloutlist td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.calloutlist>table>tbody>tr>td:first-child {
|
||||
padding-left: 10px;
|
||||
width: 30px !important;
|
||||
}
|
||||
|
||||
div.important,div.note,div.tip,div.warning {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 20px !important;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div.toc {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
dl,dt {
|
||||
margin-top: 1px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.toc>dl>dt {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dt {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dd>dl>dt {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
tbody.footnotes * {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
div.footnote p {
|
||||
margin: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.footnote p sup {
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.navheader {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
div.navfooter {
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: -1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.title>a {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0.85em;
|
||||
margin-top: 0.05em;
|
||||
margin-left: -1em;
|
||||
vertical-align: text-top;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.title>a:before {
|
||||
content: "\00A7";
|
||||
}
|
||||
|
||||
.title:hover>a,.title>a:hover,.title:hover>a:hover {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.title:focus>a,.title>a:focus,.title:focus>a:focus {
|
||||
outline: 0;
|
||||
}
|
||||
BIN
images/background.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
images/sts_exception.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
images/web-selected.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
3
multi/_additional_resources.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>1. Additional resources</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="pr01.html" title=""><link rel="next" href="_features.html" title="2. Features"></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">1. Additional resources</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="pr01.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_features.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_additional_resources" href="#_additional_resources"></a>1. Additional resources</h1></div></div></div><p><span class="strong"><strong>Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin</strong></span></p><p><a class="link" href="https://www.youtube.com/watch?v=eQV71Mw1u1c" target="_top">click here to see the video</a></p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pr01.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_features.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 2. Features</td></tr></table></div></body></html>
|
||||
149
multi/_customizations.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>8. Customizations</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_managing_spans_with_annotations.html" title="7. Managing spans with annotations"><link rel="next" href="_sending_spans_to_zipkin.html" title="9. Sending spans to Zipkin"></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">8. Customizations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_managing_spans_with_annotations.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_sending_spans_to_zipkin.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_customizations" href="#_customizations"></a>8. Customizations</h1></div></div></div><p>Thanks to the <code class="literal">SpanInjector</code> and <code class="literal">SpanExtractor</code> you can customize the way spans
|
||||
are created and propagated.</p><p>There are currently two built-in ways to pass tracing information between processes:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">via Spring Integration</li><li class="listitem">via HTTP</li></ul></div><p>Span ids are extracted from Zipkin-compatible (B3) headers (either <code class="literal">Message</code>
|
||||
or HTTP headers), to start or join an existing trace. Trace information is
|
||||
injected into any outbound requests so the next hop can extract them.</p><p>The key change in comparison to the previous versions of Sleuth is that Sleuth is implementing
|
||||
the Open Tracing’s <code class="literal">TextMap</code> notion. In Sleuth it’s called <code class="literal">SpanTextMap</code>. Basically the idea
|
||||
is that any means of communication (e.g. message, http request, etc.) can be abstracted via
|
||||
a <code class="literal">SpanTextMap</code>. This abstraction defines how one can insert data into the carrier and
|
||||
how to retrieve it from there. Thanks to this if you want to instrument a new HTTP library
|
||||
that uses a <code class="literal">FooRequest</code> as a mean of sending HTTP requests then you have to create an
|
||||
implementation of a <code class="literal">SpanTextMap</code> that delegates calls to <code class="literal">FooRequest</code> in terms of retrieval
|
||||
and insertion of HTTP headers.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_spring_integration" href="#_spring_integration"></a>8.1 Spring Integration</h3></div></div></div><p>For Spring Integration there are 2 interfaces responsible for creation of a Span from a <code class="literal">Message</code>.
|
||||
These are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">MessagingSpanTextMapExtractor</code></li><li class="listitem"><code class="literal">MessagingSpanTextMapInjector</code></li></ul></div><p>You can override them by providing your own implementation.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_http" href="#_http"></a>8.2 HTTP</h3></div></div></div><p>For HTTP there are 2 interfaces responsible for creation of a Span from a <code class="literal">Message</code>.
|
||||
These are:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">HttpSpanExtractor</code></li><li class="listitem"><code class="literal">HttpSpanInjector</code></li></ul></div><p>You can override them by providing your own implementation.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_example" href="#_example"></a>8.3 Example</h3></div></div></div><p>Let’s assume that instead of the standard Zipkin compatible tracing HTTP header names
|
||||
you have</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">for trace id - <code class="literal">correlationId</code></li><li class="listitem">for span id - <code class="literal">mySpanId</code></li></ul></div><p>This is a an example of a <code class="literal">SpanExtractor</code></p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomHttpSpanExtractor <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> HttpSpanExtractor {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Span joinTrace(SpanTextMap carrier) {
|
||||
Map<String, String> map = TextMapUtil.asMap(carrier);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">long</span> traceId = Span.hexToId(map.get(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"correlationid"</span>));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">long</span> spanId = Span.hexToId(map.get(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"myspanid"</span>));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// extract all necessary headers</span>
|
||||
Span.SpanBuilder builder = Span.builder().traceId(traceId).spanId(spanId);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// build rest of the Span</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomHttpSpanInjector <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> HttpSpanInjector {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> inject(Span span, SpanTextMap carrier) {
|
||||
carrier.put(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"correlationId"</span>, span.traceIdString());
|
||||
carrier.put(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"mySpanId"</span>, Span.idToHex(span.getSpanId()));
|
||||
}
|
||||
}</pre><p>And you could register it like this:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
HttpSpanInjector customHttpSpanInjector() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomHttpSpanInjector();
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
HttpSpanExtractor customHttpSpanExtractor() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomHttpSpanExtractor();
|
||||
}</pre><p>Spring Cloud Sleuth does not add trace/span related headers to the Http Response for security reasons. If you need the headers then a custom <code class="literal">SpanInjector</code>
|
||||
that injects the headers into the Http Response and a Servlet filter which makes use of this can be added the following way:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomHttpServletResponseSpanInjector <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> ZipkinHttpSpanInjector {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> inject(Span span, SpanTextMap carrier) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">super</span>.inject(span, carrier);
|
||||
carrier.put(Span.TRACE_ID_NAME, span.traceIdString());
|
||||
carrier.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId()));
|
||||
}
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> HttpResponseInjectingTraceFilter <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> GenericFilterBean {
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> Tracer tracer;
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> HttpSpanInjector spanInjector;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> HttpResponseInjectingTraceFilter(Tracer tracer, HttpSpanInjector spanInjector) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer = tracer;
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.spanInjector = spanInjector;
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> doFilter(ServletRequest request, ServletResponse servletResponse, FilterChain filterChain) <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> IOException, ServletException {
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
Span currentSpan = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.getCurrentSpan();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.spanInjector.inject(currentSpan, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> HttpServletResponseTextMap(response));
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> HttpServletResponseTextMap <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> SpanTextMap {
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> HttpServletResponse delegate;
|
||||
|
||||
HttpServletResponseTextMap(HttpServletResponse delegate) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.delegate = delegate;
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Iterator<Map.Entry<String, String>> iterator() {
|
||||
Map<String, String> map = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> HashMap<>();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">for</span> (String header : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.delegate.getHeaderNames()) {
|
||||
map.put(header, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.delegate.getHeader(header));
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> map.entrySet().iterator();
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> put(String key, String value) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.delegate.addHeader(key, value);
|
||||
}
|
||||
}
|
||||
}</pre><p>And you could register them like this:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em> HttpSpanInjector customHttpServletResponseSpanInjector() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomHttpServletResponseSpanInjector();
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
HttpResponseInjectingTraceFilter responseInjectingTraceFilter(Tracer tracer) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> HttpResponseInjectingTraceFilter(tracer, customHttpServletResponseSpanInjector());
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_tracefilter" href="#_tracefilter"></a>8.4 TraceFilter</h3></div></div></div><p>You can also modify the behaviour of the <code class="literal">TraceFilter</code> - the component that is responsible
|
||||
for processing the input HTTP request and adding tags basing on the HTTP response. You can customize
|
||||
the tags, or modify the response headers by registering your own instance of the <code class="literal">TraceFilter</code> bean.</p><p>In the following example we will register the <code class="literal">TraceFilter</code> bean and we will add the
|
||||
<code class="literal">ZIPKIN-TRACE-ID</code> response header containing the current Span’s trace id. Also we will
|
||||
add to the Span a tag with key <code class="literal">custom</code> and a value <code class="literal">tag</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
TraceFilter myTraceFilter(BeanFactory beanFactory, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">final</span> Tracer tracer) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceFilter(beanFactory) {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">protected</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> addResponseTags(HttpServletResponse response,
|
||||
Throwable e) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// execute the default behaviour</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">super</span>.addResponseTags(response, e);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// for readability we're returning trace id in a hex form</span>
|
||||
response.addHeader(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"ZIPKIN-TRACE-ID"</span>,
|
||||
Span.idToHex(tracer.getCurrentSpan().getTraceId()));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// we can also add some custom tags</span>
|
||||
tracer.addTag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"custom"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"tag"</span>);
|
||||
}
|
||||
};
|
||||
}</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_custom_sa_tag_in_zipkin" href="#_custom_sa_tag_in_zipkin"></a>8.5 Custom SA tag in Zipkin</h3></div></div></div><p>Sometimes you want to create a manual Span that will wrap a call to an external service which is not instrumented.
|
||||
What you can do is to create a span with the <code class="literal">peer.service</code> tag that will contain a value of the service that you want to call.
|
||||
Below you can see an example of a call to Redis that is wrapped in such a span.</p><pre class="programlisting">org.springframework.cloud.sleuth.Span newSpan = tracer.createSpan(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"redis"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">try</span> {
|
||||
newSpan.tag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"redis.op"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"get"</span>);
|
||||
newSpan.tag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"lc"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"redis"</span>);
|
||||
newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_SEND);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// call redis service e.g</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// return (SomeObj) redisTemplate.opsForHash().get("MYHASH", someObjKey);</span>
|
||||
} <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">finally</span> {
|
||||
newSpan.tag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"peer.service"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"redisService"</span>);
|
||||
newSpan.tag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"peer.ipv4"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"1.2.3.4"</span>);
|
||||
newSpan.tag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"peer.port"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"1234"</span>);
|
||||
newSpan.logEvent(org.springframework.cloud.sleuth.Span.CLIENT_RECV);
|
||||
tracer.close(newSpan);
|
||||
}</pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Remember not to add both <code class="literal">peer.service</code> tag and the <code class="literal">SA</code> tag! You have to add only <code class="literal">peer.service</code>.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_custom_service_name" href="#_custom_service_name"></a>8.6 Custom service name</h3></div></div></div><p>By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name
|
||||
to be equal to <code class="literal">spring.application.name</code> value. That’s not always the case though. There
|
||||
are situations in which you want to explicitly provide a different service name for all spans coming
|
||||
from your application. To achieve that it’s enough to just pass the following property
|
||||
to your application to override that value (example for <code class="literal">foo</code> service name):</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">spring.zipkin.service.name</span>: foo</pre></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_customization_of_reported_spans" href="#_customization_of_reported_spans"></a>8.7 Customization of reported spans</h3></div></div></div><p>Before reporting spans to e.g. Zipkin you can be interested in modifying that span in some way.
|
||||
You can achieve that by using the <code class="literal">SpanAdjuster</code> interface.</p><p>Example of usage:</p><p>In Sleuth we’re generating spans with a fixed name. Some users want to modify the name depending on values
|
||||
of tags. Implementation of the <code class="literal">SpanAdjuster</code> interface can be used to alter that name. Example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
SpanAdjuster customSpanAdjuster() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
return span -> span.toBuilder().name(scrub(span.getName())).build();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span></pre><p>This will lead in changing the name of the reported span just before it gets sent to Zipkin.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Your <code class="literal">SpanReporter</code> should inject the <code class="literal">SpanAdjuster</code> and
|
||||
allow span manipulation before the actual reporting is done.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_host_locator" href="#_host_locator"></a>8.8 Host locator</h3></div></div></div><p>In order to define the host that is corresponding to a particular span we need to resolve the host name
|
||||
and port. The default approach is to take it from server properties. If those for some reason are not set
|
||||
then we’re trying to retrieve the host name from the network interfaces.</p><p>If you have the discovery client enabled and prefer to retrieve the host address from the registered
|
||||
instance in a service registry then you have to set the property (it’s applicable for both HTTP and
|
||||
Stream based span reporting).</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">spring.zipkin.locator.discovery.enabled</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">true</span></pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_managing_spans_with_annotations.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_sending_spans_to_zipkin.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7. Managing spans with annotations </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 9. Sending spans to Zipkin</td></tr></table></div></body></html>
|
||||
22
multi/_features.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>2. Features</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_additional_resources.html" title="1. Additional resources"><link rel="next" href="_sampling.html" title="3. Sampling"></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">2. Features</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_additional_resources.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_sampling.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_features" href="#_features"></a>2. Features</h1></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p class="simpara">Adds trace and span ids to the Slf4J MDC, so you can extract all the logs from a given trace or span in a log aggregator. Example logs:</p><pre class="screen">2016-02-02 15:30:57.902 INFO [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] ...
|
||||
2016-02-02 15:30:58.372 ERROR [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] ...
|
||||
2016-02-02 15:31:01.936 INFO [bar,46ab0d418373cbc9,46ab0d418373cbc9,false] 23030 --- [nio-8081-exec-4] ...</pre><p class="simpara">notice the <code class="literal">[appname,traceId,spanId,exportable]</code> entries from the MDC:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><span class="strong"><strong>spanId</strong></span> - the id of a specific operation that took place</li><li class="listitem"><span class="strong"><strong>appname</strong></span> - the name of the application that logged the span</li><li class="listitem"><span class="strong"><strong>traceId</strong></span> - the id of the latency graph that contains the span</li><li class="listitem"><span class="strong"><strong>exportable</strong></span> - whether the log should be exported to Zipkin or not. When would you like the span not to be
|
||||
exportable? In the case in which you want to wrap some operation in a Span and have it written to the logs
|
||||
only.</li></ul></div></li><li class="listitem">Provides an abstraction over common distributed tracing data models: traces, spans (forming a DAG), annotations,
|
||||
key-value annotations. Loosely based on HTrace, but Zipkin (Dapper) compatible.</li><li class="listitem"><p class="simpara">Sleuth records timing information to aid in latency analysis. Using sleuth, you can pinpoint causes of
|
||||
latency in your applications. Sleuth is written to not log too much, and to not cause your production application to crash.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">propagates structural data about your call-graph in-band, and the rest out-of-band.</li><li class="listitem">includes opinionated instrumentation of layers such as HTTP</li><li class="listitem">includes sampling policy to manage volume</li><li class="listitem">can report to a Zipkin system for query and visualization</li></ul></div></li><li class="listitem">Instruments common ingress and egress points from Spring applications (servlet filter, async endpoints,
|
||||
rest template, scheduled actions, message channels, zuul filters, feign client).</li><li class="listitem">Sleuth includes default logic to join a trace across http or messaging boundaries. For example, http propagation
|
||||
works via Zipkin-compatible request headers. This propagation logic is defined and customized via
|
||||
<code class="literal">SpanInjector</code> and <code class="literal">SpanExtractor</code> implementations.</li><li class="listitem">Sleuth gives you the possibility to propagate context (also known as baggage) between processes. That means that if you set on a Span
|
||||
a baggage element then it will be sent downstream either via HTTP or messaging to other processes.</li><li class="listitem">Provides a way to create / continue spans and add tags and logs via annotations.</li><li class="listitem">Provides simple metrics of accepted / dropped spans.</li><li class="listitem">If <code class="literal">spring-cloud-sleuth-zipkin</code> then the app will generate and collect Zipkin-compatible traces.
|
||||
By default it sends them via HTTP to a Zipkin server on localhost (port 9411).
|
||||
Configure the location of the service using <code class="literal">spring.zipkin.baseUrl</code>.</li><li class="listitem">If <code class="literal">spring-cloud-sleuth-stream</code> then the app will generate and collect traces via <a class="link" href="https://github.com/spring-cloud/spring-cloud-stream" target="_top">Spring Cloud Stream</a>.
|
||||
Your app automatically becomes a producer of tracer messages that are sent over your broker of choice
|
||||
(e.g. RabbitMQ, Apache Kafka, Redis).</li></ul></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>If using Zipkin or Stream, configure the percentage of spans exported using <code class="literal">spring.sleuth.sampler.percentage</code>
|
||||
(default 0.1, i.e. 10%). <span class="strong"><strong>Otherwise you might think that Sleuth is not working cause it’s omitting some spans.</strong></span></p></td></tr></table></div><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>the SLF4J MDC is always set and logback users will immediately see the trace and span ids in logs per the example
|
||||
above. Other logging systems have to configure their own formatter to get the same result. The default is
|
||||
<code class="literal">logging.pattern.level</code> set to <code class="literal">%5p [${spring.zipkin.service.name:${spring.application.name:-}},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]</code>
|
||||
(this is a Spring Boot feature for logback users).
|
||||
<span class="strong"><strong>This means that if you’re not using SLF4J this pattern WILL NOT be automatically applied</strong></span>.</p></td></tr></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_additional_resources.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_sampling.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1. Additional resources </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 3. Sampling</td></tr></table></div></body></html>
|
||||
18
multi/_instrumentation.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>4. Instrumentation</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_sampling.html" title="3. Sampling"><link rel="next" href="_span_lifecycle.html" title="5. Span lifecycle"></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">4. Instrumentation</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_sampling.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_span_lifecycle.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_instrumentation" href="#_instrumentation"></a>4. Instrumentation</h1></div></div></div><p>Spring Cloud Sleuth instruments all your Spring application
|
||||
automatically, so you shouldn’t have to do anything to activate
|
||||
it. The instrumentation is added using a variety of technologies
|
||||
according to the stack that is available, e.g. for a servlet web
|
||||
application we use a <code class="literal">Filter</code>, and for Spring Integration we use
|
||||
<code class="literal">ChannelInterceptors</code>.</p><p>You can customize the keys used in span tags. To limit the volume of
|
||||
span data, by default an HTTP request will be tagged only with a
|
||||
handful of metadata like the status code, host and URL. You can add
|
||||
request headers by configuring <code class="literal">spring.sleuth.keys.http.headers</code> (a
|
||||
list of header names).</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>Remember that tags are only collected and exported if there is a
|
||||
<code class="literal">Sampler</code> that allows it (by default there is not, so there is no
|
||||
danger of accidentally collecting too much data without configuring
|
||||
something).</p></td></tr></table></div><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>Currently the instrumentation in Spring Cloud Sleuth is eager - it means that
|
||||
we’re actively trying to pass the tracing context between threads. Also timing events
|
||||
are captured even when sleuth isn’t exporting data to a tracing system.
|
||||
This approach may change in the future towards being lazy on this matter.</p></td></tr></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_sampling.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_span_lifecycle.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3. Sampling </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 5. Span lifecycle</td></tr></table></div></body></html>
|
||||
160
multi/_integrations.html
Normal file
@@ -0,0 +1,160 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>12. Integrations</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_metrics.html" title="11. Metrics"><link rel="next" href="_running_examples.html" title="13. Running examples"></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">12. Integrations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_metrics.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_running_examples.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_integrations" href="#_integrations"></a>12. Integrations</h1></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_runnable_and_callable" href="#_runnable_and_callable"></a>12.1 Runnable and Callable</h3></div></div></div><p>If you’re wrapping your logic in <code class="literal">Runnable</code> or <code class="literal">Callable</code> it’s enough to wrap those classes in their Sleuth representative.</p><p>Example for <code class="literal">Runnable</code>:</p><pre class="programlisting">Runnable runnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Runnable() {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> run() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// do some work</span>
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String toString() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"spanNameFromToStringMethod"</span>;
|
||||
}
|
||||
};
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Manual `TraceRunnable` creation with explicit "calculateTax" Span name</span>
|
||||
Runnable traceRunnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceRunnable(tracer, spanNamer, runnable, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Wrapping `Runnable` with `Tracer`. The Span name will be taken either from the</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// `@SpanName` annotation or from `toString` method</span>
|
||||
Runnable traceRunnableFromTracer = tracer.wrap(runnable);</pre><p>Example for <code class="literal">Callable</code>:</p><pre class="programlisting">Callable<String> callable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Callable<String>() {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String call() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String toString() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"spanNameFromToStringMethod"</span>;
|
||||
}
|
||||
};
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Manual `TraceCallable` creation with explicit "calculateTax" Span name</span>
|
||||
Callable<String> traceCallable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceCallable<>(tracer, spanNamer, callable, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Wrapping `Callable` with `Tracer`. The Span name will be taken either from the</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// `@SpanName` annotation or from `toString` method</span>
|
||||
Callable<String> traceCallableFromTracer = tracer.wrap(callable);</pre><p>That way you will ensure that a new Span is created and closed for each execution.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_hystrix" href="#_hystrix"></a>12.2 Hystrix</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_custom_concurrency_strategy" href="#_custom_concurrency_strategy"></a>Custom Concurrency Strategy</h4></div></div></div><p>We’re registering a custom <a class="link" href="https://github.com/Netflix/Hystrix/wiki/Plugins#concurrencystrategy" target="_top"><code class="literal">HystrixConcurrencyStrategy</code></a>
|
||||
that wraps all <code class="literal">Callable</code> instances into their Sleuth representative -
|
||||
the <code class="literal">TraceCallable</code>. The strategy either starts or continues a span depending on the fact whether tracing was already going
|
||||
on before the Hystrix command was called. To disable the custom Hystrix Concurrency Strategy set the <code class="literal">spring.sleuth.hystrix.strategy.enabled</code> to <code class="literal">false</code>.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_manual_command_setting" href="#_manual_command_setting"></a>Manual Command setting</h4></div></div></div><p>Assuming that you have the following <code class="literal">HystrixCommand</code>:</p><pre class="programlisting">HystrixCommand<String> hystrixCommand = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> HystrixCommand<String>(setter) {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">protected</span> String run() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
||||
}
|
||||
};</pre><p>In order to pass the tracing information you have to wrap the same logic in the Sleuth version of the <code class="literal">HystrixCommand</code> which is the
|
||||
<code class="literal">TraceCommand</code>:</p><pre class="programlisting">TraceCommand<String> traceCommand = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceCommand<String>(tracer, traceKeys, setter) {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String doRun() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> someLogic();
|
||||
}
|
||||
};</pre></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_rxjava" href="#_rxjava"></a>12.3 RxJava</h3></div></div></div><p>We’re registering a custom <a class="link" href="https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook" target="_top"><code class="literal">RxJavaSchedulersHook</code></a>
|
||||
that wraps all <code class="literal">Action0</code> instances into their Sleuth representative -
|
||||
the <code class="literal">TraceAction</code>. The hook either starts or continues a span depending on the fact whether tracing was already going
|
||||
on before the Action was scheduled. To disable the custom RxJavaSchedulersHook set the <code class="literal">spring.sleuth.rxjava.schedulers.hook.enabled</code> to <code class="literal">false</code>.</p><p>You can define a list of regular expressions for thread names, for which you don’t want a Span to be created. Just provide a comma separated list
|
||||
of regular expressions in the <code class="literal">spring.sleuth.rxjava.schedulers.ignoredthreads</code> property.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_http_integration" href="#_http_integration"></a>12.4 HTTP integration</h3></div></div></div><p>Features from this section can be disabled by providing the <code class="literal">spring.sleuth.web.enabled</code> property with value equal to <code class="literal">false</code>.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_http_filter" href="#_http_filter"></a>HTTP Filter</h4></div></div></div><p>Via the <code class="literal">TraceFilter</code> all sampled incoming requests result in creation of a Span. That Span’s name is <code class="literal">http:</code> + the path to which
|
||||
the request was sent. E.g. if the request was sent to <code class="literal">/foo/bar</code> then the name will be <code class="literal">http:/foo/bar</code>. You can configure which URIs you would
|
||||
like to skip via the <code class="literal">spring.sleuth.web.skipPattern</code> property. If you have <code class="literal">ManagementServerProperties</code> on classpath then
|
||||
its value of <code class="literal">contextPath</code> gets appended to the provided skip pattern.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_handlerinterceptor" href="#_handlerinterceptor"></a>HandlerInterceptor</h4></div></div></div><p>Since we want the span names to be precise we’re using a <code class="literal">TraceHandlerInterceptor</code> that either wraps an
|
||||
existing <code class="literal">HandlerInterceptor</code> or is added directly to the list of existing <code class="literal">HandlerInterceptors</code>. The
|
||||
<code class="literal">TraceHandlerInterceptor</code> adds a special request attribute to the given <code class="literal">HttpServletRequest</code>. If the
|
||||
the <code class="literal">TraceFilter</code> doesn’t see this attribute set it will create a "fallback" span which is an additional
|
||||
span created on the server side so that the trace is presented properly in the UI. Seeing that most likely
|
||||
signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_async_servlet_support" href="#_async_servlet_support"></a>Async Servlet support</h4></div></div></div><p>If your controller returns a <code class="literal">Callable</code> or a <code class="literal">WebAsyncTask</code> Spring Cloud Sleuth will continue the existing span instead of creating a new one.</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_http_client_integration" href="#_http_client_integration"></a>12.5 HTTP client integration</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_synchronous_rest_template" href="#_synchronous_rest_template"></a>Synchronous Rest Template</h4></div></div></div><p>We’re injecting a <code class="literal">RestTemplate</code> interceptor that ensures that all the tracing information is passed to the requests. Each time a
|
||||
call is made a new Span is created. It gets closed upon receiving the response. In order to block the synchronous <code class="literal">RestTemplate</code> features
|
||||
just set <code class="literal">spring.sleuth.web.client.enabled</code> to <code class="literal">false</code>.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>You have to register <code class="literal">RestTemplate</code> as a bean so that the interceptors will get injected.
|
||||
If you create a <code class="literal">RestTemplate</code> instance with a <code class="literal">new</code> keyword then the instrumentation WILL NOT work.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_asynchronous_rest_template" href="#_asynchronous_rest_template"></a>Asynchronous Rest Template</h4></div></div></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>A traced version of an <code class="literal">AsyncRestTemplate</code> bean is registered for you out of the box. If you
|
||||
have your own bean you have to wrap it in a <code class="literal">TraceAsyncRestTemplate</code> representation. The best solution
|
||||
is to only customize the <code class="literal">ClientHttpRequestFactory</code> and / or <code class="literal">AsyncClientHttpRequestFactory</code>.
|
||||
<span class="strong"><strong>If you have your own <code class="literal">AsyncRestTemplate</code> and you don’t wrap it your calls WILL NOT GET TRACED</strong></span>.</p></td></tr></table></div><p>Custom instrumentation is set to create and close Spans upon sending and receiving requests. You can customize the <code class="literal">ClientHttpRequestFactory</code>
|
||||
and the <code class="literal">AsyncClientHttpRequestFactory</code> by registering your beans. Remember to use tracing compatible implementations (e.g. don’t forget to
|
||||
wrap <code class="literal">ThreadPoolTaskScheduler</code> in a <code class="literal">TraceAsyncListenableTaskExecutor</code>). Example of custom request factories:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> TestConfiguration {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
ClientHttpRequestFactory mySyncClientFactory() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> MySyncClientHttpRequestFactory();
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
AsyncClientHttpRequestFactory myAsyncClientFactory() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> MyAsyncClientHttpRequestFactory();
|
||||
}
|
||||
}</pre><p>To block the <code class="literal">AsyncRestTemplate</code> features set <code class="literal">spring.sleuth.web.async.client.enabled</code> to <code class="literal">false</code>.
|
||||
To disable creation of the default <code class="literal">TraceAsyncClientHttpRequestFactoryWrapper</code> set <code class="literal">spring.sleuth.web.async.client.factory.enabled</code>
|
||||
to <code class="literal">false</code>. If you don’t want to create <code class="literal">AsyncRestClient</code> at all set <code class="literal">spring.sleuth.web.async.client.template.enabled</code> to <code class="literal">false</code>.</p><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_multiple_asynchronous_rest_templates" href="#_multiple_asynchronous_rest_templates"></a>Multiple Asynchronous Rest Templates</h5></div></div></div><p>Sometimes you need to use multiple implementations of Asynchronous Rest Template. In the following snippet you
|
||||
can see an example of how to set up such a custom <code class="literal">AsyncRestTemplate</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Config {
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> Tracer tracer;
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> HttpTraceKeysInjector httpTraceKeysInjector;
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> HttpSpanInjector spanInjector;
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean(name = "customAsyncRestTemplate")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> AsyncRestTemplate traceAsyncRestTemplate(<em><span class="hl-annotation" style="color: gray">@Qualifier("customHttpRequestFactoryWrapper")</span></em>
|
||||
TraceAsyncClientHttpRequestFactoryWrapper wrapper, ErrorParser errorParser) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceAsyncRestTemplate(wrapper, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer, errorParser);
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean(name = "customHttpRequestFactoryWrapper")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> TraceAsyncClientHttpRequestFactoryWrapper traceAsyncClientHttpRequestFactory() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceAsyncClientHttpRequestFactoryWrapper(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer,
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.spanInjector,
|
||||
asyncClientFactory(),
|
||||
clientHttpRequestFactory(),
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.httpTraceKeysInjector);
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> ClientHttpRequestFactory clientHttpRequestFactory() {
|
||||
ClientHttpRequestFactory clientHttpRequestFactory = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomClientHttpRequestFactory();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//CUSTOMIZE HERE</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> clientHttpRequestFactory;
|
||||
}
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> AsyncClientHttpRequestFactory asyncClientFactory() {
|
||||
AsyncClientHttpRequestFactory factory = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> CustomAsyncClientHttpRequestFactory();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//CUSTOMIZE HERE</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> factory;
|
||||
}
|
||||
}</pre></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_traverson" href="#_traverson"></a>Traverson</h4></div></div></div><p>If you’re using the <a class="link" href="http://docs.spring.io/spring-hateoas/docs/current/reference/html/#client.traverson" target="_top">Traverson</a> library
|
||||
it’s enough for you to inject a <code class="literal">RestTemplate</code> as a bean into your Traverson object. Since <code class="literal">RestTemplate</code>
|
||||
is already intercepted, you will get full support of tracing in your client. Below you can find a pseudo code
|
||||
of how to do that:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Autowired</span></em> RestTemplate restTemplate;
|
||||
|
||||
Traverson traverson = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Traverson(URI.create(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"http://some/address"</span>),
|
||||
MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// use Traverson</span></pre></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_feign" href="#_feign"></a>12.6 Feign</h3></div></div></div><p>By default Spring Cloud Sleuth provides integration with feign via the <code class="literal">TraceFeignClientAutoConfiguration</code>. You can disable it entirely
|
||||
by setting <code class="literal">spring.sleuth.feign.enabled</code> to false. If you do so then no Feign related instrumentation will take place.</p><p>Part of Feign instrumentation is done via a <code class="literal">FeignBeanPostProcessor</code>. You can disable it by providing the <code class="literal">spring.sleuth.feign.processor.enabled</code> equal to <code class="literal">false</code>.
|
||||
If you set it like this then Spring Cloud Sleuth will not instrument any of your custom Feign components. All the default instrumentation
|
||||
however will be still there.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_asynchronous_communication" href="#_asynchronous_communication"></a>12.7 Asynchronous communication</h3></div></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="__async_annotated_methods" href="#__async_annotated_methods"></a>@Async annotated methods</h4></div></div></div><p>In Spring Cloud Sleuth we’re instrumenting async related components so that the tracing information is passed between threads.
|
||||
You can disable this behaviour by setting the value of <code class="literal">spring.sleuth.async.enabled</code> to <code class="literal">false</code>.</p><p>If you annotate your method with <code class="literal">@Async</code> then we’ll automatically create a new Span with the following characteristics:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">if the method is annotated with <code class="literal">@SpanName</code> then the value of the annotation will be the Span’s name</li><li class="listitem">if the method is <span class="strong"><strong>not</strong></span> annotated with <code class="literal">@SpanName</code> the Span name will be the annotated method name</li><li class="listitem">the Span will be tagged with that method’s class name and the method name too</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="__scheduled_annotated_methods" href="#__scheduled_annotated_methods"></a>@Scheduled annotated methods</h4></div></div></div><p>In Spring Cloud Sleuth we’re instrumenting scheduled method execution so that the tracing information is passed between threads. You can disable this behaviour
|
||||
by setting the value of <code class="literal">spring.sleuth.scheduled.enabled</code> to <code class="literal">false</code>.</p><p>If you annotate your method with <code class="literal">@Scheduled</code> then we’ll automatically create a new Span with the following characteristics:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">the Span name will be the annotated method name</li><li class="listitem">the Span will be tagged with that method’s class name and the method name too</li></ul></div><p>If you want to skip Span creation for some <code class="literal">@Scheduled</code> annotated classes you can set the
|
||||
<code class="literal">spring.sleuth.scheduled.skipPattern</code> with a regular expression that will match the fully qualified name of the
|
||||
<code class="literal">@Scheduled</code> annotated class.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>If you are using <code class="literal">spring-cloud-sleuth-stream</code> and <code class="literal">spring-cloud-netflix-hystrix-stream</code> together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting <code class="literal">spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask</code></p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_executor_executorservice_and_scheduledexecutorservice" href="#_executor_executorservice_and_scheduledexecutorservice"></a>Executor, ExecutorService and ScheduledExecutorService</h4></div></div></div><p>We’re providing <code class="literal">LazyTraceExecutor</code>, <code class="literal">TraceableExecutorService</code> and <code class="literal">TraceableScheduledExecutorService</code>. Those implementations
|
||||
are creating Spans each time a new task is submitted, invoked or scheduled.</p><p>Here you can see an example of how to pass tracing information with <code class="literal">TraceableExecutorService</code> when working with <code class="literal">CompletableFuture</code>:</p><pre class="programlisting">CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// perform some logic</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span class="hl-number">1</span>_<span class="hl-number">000</span>_<span class="hl-number">000L</span>;
|
||||
}, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceableExecutorService(executorService,
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// 'calculateTax' explicitly names the span - this param is optional</span>
|
||||
tracer, traceKeys, spanNamer, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>));</pre><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_customization_of_executors" href="#_customization_of_executors"></a>Customization of Executors</h5></div></div></div><p>Sometimes you need to set up a custom instance of the <code class="literal">AsyncExecutor</code>. In the following snippet you
|
||||
can see an example of how to set up such a custom <code class="literal">Executor</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@EnableAutoConfiguration</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@EnableAsync</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomExecutorConfig <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> AsyncConfigurerSupport {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> BeanFactory beanFactory;
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Executor getAsyncExecutor() {
|
||||
ThreadPoolTaskExecutor executor = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> ThreadPoolTaskExecutor();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// CUSTOMIZE HERE</span>
|
||||
executor.setCorePoolSize(<span class="hl-number">7</span>);
|
||||
executor.setMaxPoolSize(<span class="hl-number">42</span>);
|
||||
executor.setQueueCapacity(<span class="hl-number">11</span>);
|
||||
executor.setThreadNamePrefix(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"MyExecutor-"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// DON'T FORGET TO INITIALIZE</span>
|
||||
executor.initialize();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> LazyTraceExecutor(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.beanFactory, executor);
|
||||
}
|
||||
}</pre></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_messaging" href="#_messaging"></a>12.8 Messaging</h3></div></div></div><p>Spring Cloud Sleuth integrates with <a class="link" href="http://projects.spring.io/spring-integration/" target="_top">Spring Integration</a>. It creates spans for publish and
|
||||
subscribe events. To disable Spring Integration instrumentation, set <code class="literal">spring.sleuth.integration.enabled</code> to false.</p><p>You can provide the <code class="literal">spring.sleuth.integration.patterns</code> pattern to explicitly
|
||||
provide the names of channels that you want to include for tracing. By default all channels
|
||||
are included.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>When using the <code class="literal">Executor</code> to build a Spring Integration <code class="literal">IntegrationFlow</code> remember to use the <span class="strong"><strong>untraced</strong></span> version of the <code class="literal">Executor</code>.
|
||||
Decorating Spring Integration Executor Channel with <code class="literal">TraceableExecutorService</code> will cause the spans to be improperly closed.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_zuul" href="#_zuul"></a>12.9 Zuul</h3></div></div></div><p>We’re registering Zuul filters to propagate the tracing information (the request header is enriched with tracing data).
|
||||
To disable Zuul support set the <code class="literal">spring.sleuth.zuul.enabled</code> property to <code class="literal">false</code>.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_metrics.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_running_examples.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11. Metrics </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 13. Running examples</td></tr></table></div></body></html>
|
||||
47
multi/_managing_spans_with_annotations.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>7. Managing spans with annotations</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_naming_spans.html" title="6. Naming spans"><link rel="next" href="_customizations.html" title="8. Customizations"></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">7. Managing spans with annotations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_naming_spans.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_customizations.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_managing_spans_with_annotations" href="#_managing_spans_with_annotations"></a>7. Managing spans with annotations</h1></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_rationale" href="#_rationale"></a>7.1 Rationale</h3></div></div></div><p>The main arguments for this features are</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p class="simpara">api-agnostic means to collaborate with a span</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">use of annotations allows users to add to a span with no library dependency on a span api.
|
||||
This allows Sleuth to change its core api less impact to user code.</li></ul></div></li><li class="listitem"><p class="simpara">reduced surface area for basic span operations.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">without this feature one has to use the span api, which has lifecycle commands that
|
||||
could be used incorrectly. By only exposing scope, tag and log functionality, users can
|
||||
collaborate without accidentally breaking span lifecycle.</li></ul></div></li><li class="listitem"><p class="simpara">collaboration with runtime generated code</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">with libraries such as Spring Data / Feign the implementations of interfaces are generated
|
||||
at runtime thus span wrapping of objects was tedious. Now you can provide annotations
|
||||
over interfaces and arguments of those interfaces</li></ul></div></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_creating_new_spans" href="#_creating_new_spans"></a>7.2 Creating new spans</h3></div></div></div><p>If you really don’t want to take care of creating local spans manually you can profit from the
|
||||
<code class="literal">@NewSpan</code> annotation. Also we give you the <code class="literal">@SpanTag</code> annotation to add tags in an automated
|
||||
fashion.</p><p>Let’s look at some examples of usage.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> testMethod();</pre><p>Annotating the method without any parameter will lead to a creation of a new span whose name
|
||||
will be equal to annotated method name.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan("customNameOnTestMethod4")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> testMethod4();</pre><p>If you provide the value in the annotation (either directly or via the <code class="literal">name</code> parameter) then
|
||||
the created span will have the name as the provided value.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// method declaration</span>
|
||||
<em><span class="hl-annotation" style="color: gray">@NewSpan(name = "customNameOnTestMethod5")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> testMethod5(<em><span class="hl-annotation" style="color: gray">@SpanTag("testTag")</span></em> String param);
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// and method execution</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.testBean.testMethod5(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"test"</span>);</pre><p>You can combine both the name and a tag. Let’s focus on the latter. In this case whatever the value of
|
||||
the annotated method’s parameter runtime value will be - that will be the value of the tag. In our sample
|
||||
the tag key will be <code class="literal">testTag</code> and the tag value will be <code class="literal">test</code>.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan(name = "customNameOnTestMethod3")</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> testMethod3() {
|
||||
}</pre><p>You can place the <code class="literal">@NewSpan</code> annotation on both the class and an interface. If you override the
|
||||
interface’s method and provide a different value of the <code class="literal">@NewSpan</code> annotation then the most
|
||||
concrete one wins (in this case <code class="literal">customNameOnTestMethod3</code> will be set).</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_continuing_spans" href="#_continuing_spans"></a>7.3 Continuing spans</h3></div></div></div><p>If you want to just add tags and annotations to an existing span it’s enough
|
||||
to use the <code class="literal">@ContinueSpan</code> annotation as presented below. Note that in contrast
|
||||
with the <code class="literal">@NewSpan</code> annotation you can also add logs via the <code class="literal">log</code> parameter:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// method declaration</span>
|
||||
<em><span class="hl-annotation" style="color: gray">@ContinueSpan(log = "testMethod11")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> testMethod11(<em><span class="hl-annotation" style="color: gray">@SpanTag("testTag11")</span></em> String param);
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// method execution</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.testBean.testMethod11(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"test"</span>);</pre><p>That way the span will get continued and:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">logs with name <code class="literal">testMethod11.before</code> and <code class="literal">testMethod11.after</code> will be created</li><li class="listitem">if an exception will be thrown a log <code class="literal">testMethod11.afterFailure</code> will also be created</li><li class="listitem">tag with key <code class="literal">testTag11</code> and value <code class="literal">test</code> will be created</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_more_advanced_tag_setting" href="#_more_advanced_tag_setting"></a>7.4 More advanced tag setting</h3></div></div></div><p>There are 3 different ways to add tags to a span. All of them are controlled by the <code class="literal">SpanTag</code> annotation.
|
||||
Precedence is:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">try with the bean of <code class="literal">TagValueResolver</code> type and provided name</li><li class="listitem">if one hasn’t provided the bean name, try to evaluate an expression. We’re searching for a <code class="literal">TagValueExpressionResolver</code> bean.
|
||||
The default implementation uses SPEL expression resolution.</li><li class="listitem">if one hasn’t provided any expression to evaluate just return a <code class="literal">toString()</code> value of the parameter</li></ul></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_custom_extractor" href="#_custom_extractor"></a>Custom extractor</h4></div></div></div><p>The value of the tag for following method will be computed by an implementation of <code class="literal">TagValueResolver</code> interface.
|
||||
Its class name has to be passed as the value of the <code class="literal">resolver</code> attribute.</p><p>Having such an annotated method:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> getAnnotationForTagValueResolver(<em><span class="hl-annotation" style="color: gray">@SpanTag(key = "test", resolver = TagValueResolver.class)</span></em> String test) {
|
||||
}</pre><p>and such a <code class="literal">TagValueResolver</code> bean implementation</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean(name = "myCustomTagValueResolver")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> TagValueResolver tagValueResolver() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> parameter -> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Value from myCustomTagValueResolver"</span>;
|
||||
}</pre><p>Will lead to setting of a tag value equal to <code class="literal">Value from myCustomTagValueResolver</code>.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_resolving_expressions_for_value" href="#_resolving_expressions_for_value"></a>Resolving expressions for value</h4></div></div></div><p>Having such an annotated method:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> getAnnotationForTagValueExpression(<em><span class="hl-annotation" style="color: gray">@SpanTag(key = "test", expression = "length() + ' characters'")</span></em> String test) {
|
||||
}</pre><p>and no custom implementation of a <code class="literal">TagValueExpressionResolver</code> will lead to evaluation of the SPEL expression and a tag with value <code class="literal">4 characters</code> will be set on the span.
|
||||
If you want to use some other expression resolution mechanism you can create your own implementation
|
||||
of the bean.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_using_tostring_method" href="#_using_tostring_method"></a>Using toString method</h4></div></div></div><p>Having such an annotated method:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@NewSpan</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> getAnnotationForArgumentToString(<em><span class="hl-annotation" style="color: gray">@SpanTag("test")</span></em> Long param) {
|
||||
}</pre><p>if executed with a value of <code class="literal">15</code> will lead to setting of a tag with a String value of <code class="literal">"15"</code>.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_naming_spans.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_customizations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6. Naming spans </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 8. Customizations</td></tr></table></div></body></html>
|
||||
7
multi/_metrics.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>11. Metrics</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_span_data_as_messages.html" title="10. Span Data as Messages"><link rel="next" href="_integrations.html" title="12. Integrations"></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">11. Metrics</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_span_data_as_messages.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_integrations.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_metrics" href="#_metrics"></a>11. Metrics</h1></div></div></div><p>Currently Spring Cloud Sleuth registers very simple metrics related to spans.
|
||||
It’s using the <a class="link" href="http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html#production-ready-recording-metrics" target="_top">Spring Boot’s metrics support</a>
|
||||
to calculate the number of accepted and dropped spans. Each time a span gets
|
||||
sent to Zipkin the number of accepted spans will increase. If there’s an error then
|
||||
the number of dropped spans will get increased.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_span_data_as_messages.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_integrations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10. Span Data as Messages </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 12. Integrations</td></tr></table></div></body></html>
|
||||
27
multi/_naming_spans.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>6. Naming spans</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_span_lifecycle.html" title="5. Span lifecycle"><link rel="next" href="_managing_spans_with_annotations.html" title="7. Managing spans with annotations"></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">6. Naming spans</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_span_lifecycle.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_managing_spans_with_annotations.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_naming_spans" href="#_naming_spans"></a>6. Naming spans</h1></div></div></div><p>Picking a span name is not a trivial task. Span name should depict an operation name. The name should
|
||||
be low cardinality (e.g. not include identifiers).</p><p>Since there is a lot of instrumentation going on some of the span names will be
|
||||
artificial like:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">controller-method-name</code> when received by a Controller with a method name <code class="literal">conrollerMethodName</code></li><li class="listitem"><code class="literal">async</code> for asynchronous operations done via wrapped <code class="literal">Callable</code> and <code class="literal">Runnable</code>.</li><li class="listitem"><code class="literal">@Scheduled</code> annotated methods will return the simple name of the class.</li></ul></div><p>Fortunately, for the asynchronous processing you can provide explicit naming.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="__spanname_annotation" href="#__spanname_annotation"></a>6.1 @SpanName annotation</h3></div></div></div><p>You can name the span explicitly via the <code class="literal">@SpanName</code> annotation.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@SpanName("calculateTax")</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> TaxCountingRunnable <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">implements</span> Runnable {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> run() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// perform logic</span>
|
||||
}
|
||||
}</pre><p>In this case, when processed in the following manner:</p><pre class="programlisting">Runnable runnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceRunnable(tracer, spanNamer, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TaxCountingRunnable());
|
||||
Future<?> future = executorService.submit(runnable);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ... some additional logic ...</span>
|
||||
future.get();</pre><p>The span will be named <code class="literal">calculateTax</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_tostring_method" href="#_tostring_method"></a>6.2 toString() method</h3></div></div></div><p>It’s pretty rare to create separate classes for <code class="literal">Runnable</code> or <code class="literal">Callable</code>. Typically one creates an anonymous
|
||||
instance of those classes. You can’t annotate such classes thus to override that, if there is no <code class="literal">@SpanName</code> annotation present,
|
||||
we’re checking if the class has a custom implementation of the <code class="literal">toString()</code> method.</p><p>So executing such code:</p><pre class="programlisting">Runnable runnable = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> TraceRunnable(tracer, spanNamer, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> Runnable() {
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> run() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// perform logic</span>
|
||||
}
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Override</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> String toString() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>;
|
||||
}
|
||||
});
|
||||
Future<?> future = executorService.submit(runnable);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ... some additional logic ...</span>
|
||||
future.get();</pre><p>will lead in creating a span named <code class="literal">calculateTax</code>.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_span_lifecycle.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_managing_spans_with_annotations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. Span lifecycle </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 7. Managing spans with annotations</td></tr></table></div></body></html>
|
||||
3
multi/_running_examples.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>13. Running examples</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_integrations.html" title="12. Integrations"></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">13. Running examples</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_integrations.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_running_examples" href="#_running_examples"></a>13. Running examples</h1></div></div></div><p>You can find the running examples deployed in the <a class="link" href="https://run.pivotal.io/" target="_top">Pivotal Web Services</a>. Check them out in the following links:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="http://docssleuth-zipkin-server.cfapps.io/" target="_top">Zipkin for apps presented in the samples to the top</a></li><li class="listitem"><a class="link" href="http://docsbrewing-zipkin-server.cfapps.io/" target="_top">Zipkin for Brewery on PWS</a>, its <a class="link" href="https://github.com/spring-cloud-samples/brewery" target="_top">Github Code</a></li></ul></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_integrations.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">12. Integrations </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html>
|
||||
26
multi/_sampling.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>3. Sampling</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_features.html" title="2. Features"><link rel="next" href="_instrumentation.html" title="4. Instrumentation"></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">3. Sampling</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_features.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_instrumentation.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_sampling" href="#_sampling"></a>3. Sampling</h1></div></div></div><p>In distributed tracing the data volumes can be very high so sampling
|
||||
can be important (you usually don’t need to export all spans to get a
|
||||
good picture of what is happening). Spring Cloud Sleuth has a
|
||||
<code class="literal">Sampler</code> strategy that you can implement to take control of the
|
||||
sampling algorithm. Samplers do not stop span (correlation) ids from
|
||||
being generated, but they do prevent the tags and events being
|
||||
attached and exported. By default you get a strategy that continues to
|
||||
trace if a span is already active, but new ones are always marked as
|
||||
non-exportable. If all your apps run with this sampler you will see
|
||||
traces in logs, but not in any remote store. For testing the default
|
||||
is often enough, and it probably is all you need if you are only using
|
||||
the logs (e.g. with an ELK aggregator). If you are exporting span data
|
||||
to Zipkin or Spring Cloud Stream, there is also an <code class="literal">AlwaysSampler</code>
|
||||
that exports everything and a <code class="literal">PercentageBasedSampler</code> that samples a
|
||||
fixed fraction of spans.</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>the <code class="literal">PercentageBasedSampler</code> is the default if you are using
|
||||
<code class="literal">spring-cloud-sleuth-zipkin</code> or <code class="literal">spring-cloud-sleuth-stream</code>. You can
|
||||
configure the exports using <code class="literal">spring.sleuth.sampler.percentage</code>. The passed
|
||||
value needs to be a double from <code class="literal">0.0</code> to <code class="literal">1.0</code> so it’s not a percentage.
|
||||
For backwards compatibility reasons we’re not changing the property name.</p></td></tr></table></div><p>A sampler can be installed just by creating a bean definition, e.g:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> Sampler defaultSampler() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> AlwaysSampler();
|
||||
}</pre><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>You can set the HTTP header <code class="literal">X-B3-Flags</code> to <code class="literal">1</code> or when doing messaging you can
|
||||
set <code class="literal">spanFlags</code> header to <code class="literal">1</code>. Then the current span will be forced to be exportable
|
||||
regardless of the sampling decision.</p></td></tr></table></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_features.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_instrumentation.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Features </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 4. Instrumentation</td></tr></table></div></body></html>
|
||||
7
multi/_sending_spans_to_zipkin.html
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>9. Sending spans to Zipkin</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_customizations.html" title="8. Customizations"><link rel="next" href="_span_data_as_messages.html" title="10. Span Data as Messages"></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">9. Sending spans to Zipkin</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_customizations.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_span_data_as_messages.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_sending_spans_to_zipkin" href="#_sending_spans_to_zipkin"></a>9. Sending spans to Zipkin</h1></div></div></div><p>By default if you add <code class="literal">spring-cloud-starter-zipkin</code> as a dependency to your project,
|
||||
when the span is closed, it will be sent to Zipkin over HTTP. The communication
|
||||
is asynchronous. You can configure the URL by setting the <code class="literal">spring.zipkin.baseUrl</code>
|
||||
property as follows:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">spring.zipkin.baseUrl</span>: http://<span class="hl-number">192.168</span>.<span class="hl-number">99.100</span>:<span class="hl-number">9411</span>/</pre><p>If you want to find Zipkin via service discovery it’s enough to pass the
|
||||
Zipkin’s service id inside the URL (example for <code class="literal">zipkinserver</code> service id)</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">spring.zipkin.baseUrl</span>: http://zipkinserver/</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_customizations.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_span_data_as_messages.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Customizations </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 10. Span Data as Messages</td></tr></table></div></body></html>
|
||||
68
multi/_span_data_as_messages.html
Normal file
@@ -0,0 +1,68 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>10. Span Data as Messages</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_sending_spans_to_zipkin.html" title="9. Sending spans to Zipkin"><link rel="next" href="_metrics.html" title="11. Metrics"></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">10. Span Data as Messages</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_sending_spans_to_zipkin.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_metrics.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_span_data_as_messages" href="#_span_data_as_messages"></a>10. Span Data as Messages</h1></div></div></div><p>You can accumulate and send span data over
|
||||
<a class="link" href="http://cloud.spring.io/spring-cloud-stream" target="_top">Spring Cloud Stream</a> by
|
||||
including the <code class="literal">spring-cloud-sleuth-stream</code> jar as a dependency, and
|
||||
adding a Channel Binder implementation
|
||||
(e.g. <code class="literal">spring-cloud-starter-stream-rabbit</code> for RabbitMQ or
|
||||
<code class="literal">spring-cloud-starter-stream-kafka</code> for Kafka). This will
|
||||
automatically turn your app into a producer of messages with payload
|
||||
type <code class="literal">Spans</code>.</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_zipkin_consumer" href="#_zipkin_consumer"></a>10.1 Zipkin Consumer</h3></div></div></div><p>There is a special convenience annotation for setting up a message consumer
|
||||
for the Span data and pushing it into a Zipkin <code class="literal">SpanStore</code>. This application</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@SpringBootApplication</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@EnableZipkinStreamServer</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Consumer {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> main(String[] args) {
|
||||
SpringApplication.run(Consumer.<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span>, args);
|
||||
}
|
||||
}</pre><p>will listen for the Span data on whatever transport you provide via a
|
||||
Spring Cloud Stream <code class="literal">Binder</code> (e.g. include
|
||||
<code class="literal">spring-cloud-starter-stream-rabbit</code> for RabbitMQ, and similar
|
||||
starters exist for Redis and Kafka). If you add the following UI dependency</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>io.zipkin.java<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>zipkin-autoconfigure-ui<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span></pre><p>Then you’ll have your app a
|
||||
<a class="link" href="https://github.com/openzipkin/zipkin" target="_top">Zipkin server</a>, which hosts
|
||||
the UI and api on port 9411.</p><p>The default <code class="literal">SpanStore</code> is in-memory (good for demos and getting
|
||||
started quickly). For a more robust solution you can add MySQL and
|
||||
<code class="literal">spring-boot-starter-jdbc</code> to your classpath and enable the JDBC
|
||||
<code class="literal">SpanStore</code> via configuration, e.g.:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">spring</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> rabbitmq</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> host</span>: ${RABBIT_HOST:localhost<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> datasource</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> schema</span>: classpath:/mysql.sql
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> url</span>: jdbc:mysql://${MYSQL_HOST:localhost}/test
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> username</span>: root
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> password</span>: root
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"># Switch this on to create the schema on startup:</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> initialize</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">true</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> continueOnError</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">true</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> sleuth</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> enabled</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">false</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">zipkin</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> storage</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> type</span>: mysql</pre><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>The <code class="literal">@EnableZipkinStreamServer</code> is also annotated with
|
||||
<code class="literal">@EnableZipkinServer</code> so the process will also expose the standard
|
||||
Zipkin server endpoints for collecting spans over HTTP, and for
|
||||
querying in the Zipkin Web UI.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_custom_consumer" href="#_custom_consumer"></a>10.2 Custom Consumer</h3></div></div></div><p>A custom consumer can also easily be implemented using
|
||||
<code class="literal">spring-cloud-sleuth-stream</code> and binding to the <code class="literal">SleuthSink</code>. Example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@EnableBinding(SleuthSink.class)</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@SpringBootApplication(exclude = SleuthStreamAutoConfiguration.class)</span></em>
|
||||
<em><span class="hl-annotation" style="color: gray">@MessageEndpoint</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> Consumer {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@ServiceActivator(inputChannel = SleuthSink.INPUT)</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> sink(Spans input) <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ... process spans</span>
|
||||
}
|
||||
}</pre><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>the sample consumer application above explicitly excludes
|
||||
<code class="literal">SleuthStreamAutoConfiguration</code> so it doesn’t send messages to itself,
|
||||
but this is optional (you might actually want to trace requests into
|
||||
the consumer app).</p></td></tr></table></div><p>In order to customize the polling mechanism you can create a bean of <code class="literal">PollerMetadata</code> type
|
||||
with name equal to <code class="literal">StreamSpanReporter.POLLER</code>. Here you can find an example of such a configuration.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Configuration</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> CustomPollerConfiguration {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Bean(name = StreamSpanReporter.POLLER)</span></em>
|
||||
PollerMetadata customPoller() {
|
||||
PollerMetadata poller = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> PollerMetadata();
|
||||
poller.setMaxMessagesPerPoll(<span class="hl-number">500</span>);
|
||||
poller.setTrigger(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> PeriodicTrigger(<span class="hl-number">5000L</span>));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> poller;
|
||||
}
|
||||
}</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_sending_spans_to_zipkin.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_metrics.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9. Sending spans to Zipkin </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 11. Metrics</td></tr></table></div></body></html>
|
||||
63
multi/_span_lifecycle.html
Normal file
@@ -0,0 +1,63 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>5. Span lifecycle</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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="_instrumentation.html" title="4. Instrumentation"><link rel="next" href="_naming_spans.html" title="6. Naming spans"></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">5. Span lifecycle</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="_instrumentation.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_naming_spans.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_span_lifecycle" href="#_span_lifecycle"></a>5. Span lifecycle</h1></div></div></div><p>You can do the following operations on the Span by means of <span class="strong"><strong>org.springframework.cloud.sleuth.Tracer</strong></span> interface:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="_span_lifecycle.html#creating-and-closing-spans" title="5.1 Creating and closing spans">start</a> - when you start a span its name is assigned and start timestamp is recorded.</li><li class="listitem"><a class="link" href="_span_lifecycle.html#creating-and-closing-spans" title="5.1 Creating and closing spans">close</a> - the span gets finished (the end time of the span is recorded) and if
|
||||
the span is <span class="strong"><strong>exportable</strong></span> then it will be eligible for collection to Zipkin.
|
||||
The span is also removed from the current thread.</li><li class="listitem"><a class="link" href="_span_lifecycle.html#continuing-spans" title="5.2 Continuing spans">continue</a> - a new instance of span will be created whereas it will be a copy of the
|
||||
one that it continues.</li><li class="listitem"><a class="link" href="_span_lifecycle.html#continuing-spans" title="5.2 Continuing spans">detach</a> - the span doesn’t get stopped or closed. It only gets removed from the current thread.</li><li class="listitem"><a class="link" href="_span_lifecycle.html#creating-spans-with-explicit-parent" title="5.3 Creating spans with an explicit parent">create with explicit parent</a> - you can create a new span and set an explicit parent to it</li></ul></div><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>Spring creates the instance of <code class="literal">Tracer</code> for you. In order to use it all you need is to just autowire it.</p></td></tr></table></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="creating-and-closing-spans" href="#creating-and-closing-spans"></a>5.1 Creating and closing spans</h3></div></div></div><p>You can manually create spans by using the <span class="strong"><strong>Tracer</strong></span> interface.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Start a span. If there was a span present in this thread it will become</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// the `newSpan`'s parent.</span>
|
||||
Span newSpan = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.createSpan(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateTax"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">try</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can tag a span</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.addTag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"taxValue"</span>, taxValue);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can log an event on a span</span>
|
||||
newSpan.logEvent(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"taxCalculated"</span>);
|
||||
} <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">finally</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Once done remember to close the span. This will allow collecting</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// the span to send it to Zipkin</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.close(newSpan);
|
||||
}</pre><p>In this example we could see how to create a new instance of span. Assuming that there already
|
||||
was a span present in this thread then it would become the parent of that span.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Always clean after you create a span! Don’t forget to close a span if you want to send it to Zipkin.</p></td></tr></table></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>If your span contains a name greater than 50 chars, then that name will
|
||||
be truncated to 50 chars. Your names have to be explicit and concrete. Big names lead to
|
||||
latency issues and sometimes even thrown exceptions.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="continuing-spans" href="#continuing-spans"></a>5.2 Continuing spans</h3></div></div></div><p>Sometimes you don’t want to create a new span but you want to continue one. Example of such a
|
||||
situation might be (of course it all depends on the use-case):</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>AOP</strong></span> - If there was already a span created before an aspect was reached then you might not want to create a new span.</li><li class="listitem"><span class="strong"><strong>Hystrix</strong></span> - executing a Hystrix command is most likely a logical part of the current processing. It’s in fact
|
||||
only a technical implementation detail that you wouldn’t necessarily want to reflect in tracing as a separate being.</li></ul></div><p>The continued instance of span is equal to the one that it continues:</p><pre class="programlisting">Span continuedSpan = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.continueSpan(spanToContinue);
|
||||
assertThat(continuedSpan).isEqualTo(spanToContinue);</pre><p>To continue a span you can use the <span class="strong"><strong>Tracer</strong></span> interface.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// let's assume that we're in a thread Y and we've received</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// the `initialSpan` from thread X</span>
|
||||
Span continuedSpan = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.continueSpan(initialSpan);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">try</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can tag a span</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.addTag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"taxValue"</span>, taxValue);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can log an event on a span</span>
|
||||
continuedSpan.logEvent(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"taxCalculated"</span>);
|
||||
} <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">finally</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Once done remember to detach the span. That way you'll</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// safely remove it from the current thread without closing it</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.detach(continuedSpan);
|
||||
}</pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>Always clean after you create a span! Don’t forget to detach a span if some work was done started in one
|
||||
thread (e.g. thread X) and it’s waiting for other threads (e.g. Y, Z) to finish.
|
||||
Then the spans in the threads Y, Z should be detached at the end of their work. When the results are collected
|
||||
the span in thread X should be closed.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="creating-spans-with-explicit-parent" href="#creating-spans-with-explicit-parent"></a>5.3 Creating spans with an explicit parent</h3></div></div></div><p>There is a possibility that you want to start a new span and provide an explicit parent of that span.
|
||||
Let’s assume that the parent of a span is in one thread and you want to start a new span in another thread. The
|
||||
<code class="literal">startSpan</code> method of the <code class="literal">Tracer</code> interface is the method you are looking for.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// let's assume that we're in a thread Y and we've received</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// the `initialSpan` from thread X. `initialSpan` will be the parent</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// of the `newSpan`</span>
|
||||
Span newSpan = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.createSpan(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"calculateCommission"</span>, initialSpan);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">try</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can tag a span</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.addTag(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"commissionValue"</span>, commissionValue);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// ...</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// You can log an event on a span</span>
|
||||
newSpan.logEvent(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"commissionCalculated"</span>);
|
||||
} <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">finally</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Once done remember to close the span. This will allow collecting</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// the span to send it to Zipkin. The tags and events set on the</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// newSpan will not be present on the parent</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.tracer.close(newSpan);
|
||||
}</pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>After having created such a span remember to close it. Otherwise you will see a lot of warnings in your logs
|
||||
related to the fact that you have a span present in the current thread other than the one you’re trying to close.
|
||||
What’s worse your spans won’t get closed properly thus will not get collected to Zipkin.</p></td></tr></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="_instrumentation.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_naming_spans.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Instrumentation </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 6. Naming spans</td></tr></table></div></body></html>
|
||||
35
multi/css/highlight.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
code highlight CSS resemblign the Eclipse IDE default color schema
|
||||
@author Costin Leau
|
||||
*/
|
||||
|
||||
.hl-keyword {
|
||||
color: #7F0055;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hl-comment {
|
||||
color: #3F5F5F;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-multiline-comment {
|
||||
color: #3F5FBF;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-tag {
|
||||
color: #3F7F7F;
|
||||
}
|
||||
|
||||
.hl-attribute {
|
||||
color: #7F007F;
|
||||
}
|
||||
|
||||
.hl-value {
|
||||
color: #2A00FF;
|
||||
}
|
||||
|
||||
.hl-string {
|
||||
color: #2A00FF;
|
||||
}
|
||||
9
multi/css/manual-multipage.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body.firstpage {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: none;
|
||||
}
|
||||
6
multi/css/manual-singlepage.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
344
multi/css/manual.css
Normal file
@@ -0,0 +1,344 @@
|
||||
@IMPORT url("highlight.css");
|
||||
|
||||
html {
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333333;
|
||||
margin: 15px 30px;
|
||||
font-family: Helvetica, Arial, Freesans, Clean, Sans-serif;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 16px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
:not(a)>code {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
:not(pre)>code {
|
||||
background-color: #F2F2F2;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px 0;
|
||||
text-shadow: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body>*:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #CCCCCC;
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000000;
|
||||
cursor: text;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1,h2,h3 {
|
||||
margin: 40px 0 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 70px 0 30px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: 1px dotted #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h1 code {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
h2,h2 code {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h3,h3 code {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h4,h1 code,h5,h5 code,h6,h6 code {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
div.book,div.chapter,div.appendix,div.part,div.preface {
|
||||
min-width: 300px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
p.releaseinfo {
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
div.authorgroup {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
p.copyright {
|
||||
line-height: 1;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
|
||||
.legalnotice p {
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.titlepage+p,div.titlepage+p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul,ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.table {
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.table table,div.informaltable table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.table td {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
line-height: 1.4;
|
||||
padding: 0 20px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
.sidebar p.title {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
pre.programlisting,pre.screen {
|
||||
font-size: 15px;
|
||||
padding: 6px 10px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
line-height: 1.4;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #DDDDDD !important;
|
||||
border-radius: 4px !important;
|
||||
border-collapse: separate !important;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
table thead {
|
||||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table th,table td {
|
||||
border: none !important;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
td p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
div.table-contents td p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist *
|
||||
{
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important p,div.note p,div.tip p,div.warning p {
|
||||
color: #6F6F6F;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
div.important code,div.note code,div.tip code,div.warning code {
|
||||
background-color: #F2F2F2 !important;
|
||||
border: 1px solid #CCCCCC !important;
|
||||
border-radius: 4px !important;
|
||||
padding: 1px 3px 0 !important;
|
||||
text-shadow: none !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.note th,.tip th,.warning th {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td
|
||||
{
|
||||
border-right: 1px solid #CCCCCC !important;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
div.calloutlist p,div.calloutlist td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.calloutlist>table>tbody>tr>td:first-child {
|
||||
padding-left: 10px;
|
||||
width: 30px !important;
|
||||
}
|
||||
|
||||
div.important,div.note,div.tip,div.warning {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 20px !important;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div.toc {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
dl,dt {
|
||||
margin-top: 1px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.toc>dl>dt {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dt {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dd>dl>dt {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
tbody.footnotes * {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
div.footnote p {
|
||||
margin: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.footnote p sup {
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.navheader {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
div.navfooter {
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: -1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.title>a {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0.85em;
|
||||
margin-top: 0.05em;
|
||||
margin-left: -1em;
|
||||
vertical-align: text-top;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.title>a:before {
|
||||
content: "\00A7";
|
||||
}
|
||||
|
||||
.title:hover>a,.title>a:hover,.title:hover>a:hover {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.title:focus>a,.title>a:focus,.title:focus>a:focus {
|
||||
outline: 0;
|
||||
}
|
||||
BIN
multi/images/background.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
multi/images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
multi/images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
multi/images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
multi/images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
multi/images/sts_exception.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
multi/images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
multi/images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
multi/images/web-selected.png
Normal file
|
After Width: | Height: | Size: 178 KiB |
3
multi/pr01.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title></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="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="up" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="prev" href="spring-cloud-sleuth.html" title="Spring Cloud Sleuth"><link rel="next" href="_additional_resources.html" title="1. Additional resources"></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"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="spring-cloud-sleuth.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="_additional_resources.html">Next</a></td></tr></table><hr></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="d0e17" href="#d0e17"></a></h1></div></div></div><p><span class="strong"><strong>1.3.0.BUILD-SNAPSHOT</strong></span></p><p>Spring Cloud Sleuth implements a distributed tracing solution for <a class="link" href="http://cloud.spring.io" target="_top">Spring Cloud</a>.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spring-cloud-sleuth.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="_additional_resources.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Spring Cloud Sleuth </td><td width="20%" align="center"><a accesskey="h" href="spring-cloud-sleuth.html">Home</a></td><td width="40%" align="right" valign="top"> 1. Additional resources</td></tr></table></div></body></html>
|
||||
297
multi/spring-cloud-sleuth.html
Normal file
35
single/css/highlight.css
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
code highlight CSS resemblign the Eclipse IDE default color schema
|
||||
@author Costin Leau
|
||||
*/
|
||||
|
||||
.hl-keyword {
|
||||
color: #7F0055;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hl-comment {
|
||||
color: #3F5F5F;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-multiline-comment {
|
||||
color: #3F5FBF;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hl-tag {
|
||||
color: #3F7F7F;
|
||||
}
|
||||
|
||||
.hl-attribute {
|
||||
color: #7F007F;
|
||||
}
|
||||
|
||||
.hl-value {
|
||||
color: #2A00FF;
|
||||
}
|
||||
|
||||
.hl-string {
|
||||
color: #2A00FF;
|
||||
}
|
||||
9
single/css/manual-multipage.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body.firstpage {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: none;
|
||||
}
|
||||
6
single/css/manual-singlepage.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@IMPORT url("manual.css");
|
||||
|
||||
body {
|
||||
background: url("../images/background.png") no-repeat center top;
|
||||
}
|
||||
|
||||
344
single/css/manual.css
Normal file
@@ -0,0 +1,344 @@
|
||||
@IMPORT url("highlight.css");
|
||||
|
||||
html {
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #333333;
|
||||
margin: 15px 30px;
|
||||
font-family: Helvetica, Arial, Freesans, Clean, Sans-serif;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 16px;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
:not(a)>code {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
:not(pre)>code {
|
||||
background-color: #F2F2F2;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 4px;
|
||||
padding: 1px 3px 0;
|
||||
text-shadow: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
body>*:first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0pt;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #CCCCCC;
|
||||
background: #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000000;
|
||||
cursor: text;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1,h2,h3 {
|
||||
margin: 40px 0 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 70px 0 30px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
div.part h1 {
|
||||
border-top: 1px dotted #CCCCCC;
|
||||
}
|
||||
|
||||
h1,h1 code {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
h2,h2 code {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h3,h3 code {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h4,h1 code,h5,h5 code,h6,h6 code {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
div.book,div.chapter,div.appendix,div.part,div.preface {
|
||||
min-width: 300px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
p.releaseinfo {
|
||||
font-weight: bold;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
div.authorgroup {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
p.copyright {
|
||||
line-height: 1;
|
||||
margin-bottom: -5px;
|
||||
}
|
||||
|
||||
.legalnotice p {
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.titlepage+p,div.titlepage+p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
line-height: 1.0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4183C4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul,ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.table {
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.table table,div.informaltable table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.table td {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
line-height: 1.4;
|
||||
padding: 0 20px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
}
|
||||
|
||||
.sidebar p.title {
|
||||
color: #6D180B;
|
||||
}
|
||||
|
||||
pre.programlisting,pre.screen {
|
||||
font-size: 15px;
|
||||
padding: 6px 10px;
|
||||
background-color: #F8F8F8;
|
||||
border: 1px solid #CCCCCC;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
clear: both;
|
||||
overflow: auto;
|
||||
line-height: 1.4;
|
||||
font-family: Consolas, "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 1px solid #DDDDDD !important;
|
||||
border-radius: 4px !important;
|
||||
border-collapse: separate !important;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
table thead {
|
||||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table th,table td {
|
||||
border: none !important;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
table tr:nth-child(2n) {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
|
||||
td p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
div.table-contents td p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important *,div.note *,div.tip *,div.warning *,div.navheader *,div.navfooter *,div.calloutlist *
|
||||
{
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.important p,div.note p,div.tip p,div.warning p {
|
||||
color: #6F6F6F;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
div.important code,div.note code,div.tip code,div.warning code {
|
||||
background-color: #F2F2F2 !important;
|
||||
border: 1px solid #CCCCCC !important;
|
||||
border-radius: 4px !important;
|
||||
padding: 1px 3px 0 !important;
|
||||
text-shadow: none !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.note th,.tip th,.warning th {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.note tr:first-child td,.tip tr:first-child td,.warning tr:first-child td
|
||||
{
|
||||
border-right: 1px solid #CCCCCC !important;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
div.calloutlist p,div.calloutlist td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.calloutlist>table>tbody>tr>td:first-child {
|
||||
padding-left: 10px;
|
||||
width: 30px !important;
|
||||
}
|
||||
|
||||
div.important,div.note,div.tip,div.warning {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 20px !important;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div.toc {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
dl,dt {
|
||||
margin-top: 1px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.toc>dl>dt {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin: 30px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dt {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0 10px 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.toc>dl>dd>dl>dd>dl>dt {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
tbody.footnotes * {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
div.footnote p {
|
||||
margin: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.footnote p sup {
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.navheader {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
div.navfooter {
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: -1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.title>a {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0.85em;
|
||||
margin-top: 0.05em;
|
||||
margin-left: -1em;
|
||||
vertical-align: text-top;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.title>a:before {
|
||||
content: "\00A7";
|
||||
}
|
||||
|
||||
.title:hover>a,.title>a:hover,.title:hover>a:hover {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.title:focus>a,.title>a:focus,.title:focus>a:focus {
|
||||
outline: 0;
|
||||
}
|
||||
BIN
single/images/background.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
single/images/caution.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
single/images/important.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
single/images/logo.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
single/images/note.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
single/images/sts_exception.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
single/images/tip.png
Normal file
|
After Width: | Height: | Size: 931 B |
BIN
single/images/warning.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
single/images/web-selected.png
Normal file
|
After Width: | Height: | Size: 178 KiB |