├── .gitignore
├── LICENSE
├── README.md
├── autoconfigure
├── pom.xml
└── storage-scouter-udp-conf
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── zipkin
│ │ └── autoconfigure
│ │ └── storage
│ │ └── scouter
│ │ ├── ZipkinScouterStorageAutoConfiguration.java
│ │ └── ZipkinScouterStorageProperties.java
│ └── resources
│ ├── META-INF
│ └── spring.factories
│ └── zipkin-server-scouter.yml
├── pom.xml
└── storage-scouter-udp
├── pom.xml
└── src
├── main
└── java
│ └── zipkin2
│ └── storage
│ └── scouter
│ ├── ScouterConstants.java
│ └── udp
│ ├── ScouterConfig.java
│ ├── ScouterUDPStorage.java
│ └── net
│ ├── DataProxy.java
│ ├── DataUdpAgent.java
│ └── UDPDataSendThread.java
└── test
└── java
└── zipkin2
└── storage
└── scouter
├── ScouterConstantsTest.java
└── udp
└── net
└── DataProxyTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | # intellij
26 | *.iml
27 |
28 | target/
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # zipkin-scouter
2 | Zipkin Scouter UDP storage and other zipkin-scouter integrations.
3 | * Supported scouter collector version : `v2.5+`
4 |
5 | ## Server integration
6 | In order to integrate with zipkin-server, you need to use properties
7 | launcher to load your collector (or sender) alongside the zipkin-server
8 | process.
9 |
10 | To integrate a module with a Zipkin server, you need to:
11 | * add a module jar to the `loader.path`
12 | * enable the profile associated with that module
13 | * launch Zipkin with `PropertiesLauncher`
14 |
15 | Each module will also have different minimum variables that need to be set.
16 |
17 |
18 | ## Example integrating the Scouter Collector by Zipkin-Scouter-Storage
19 |
20 | Here's an example of integrating the scouter Collector.
21 |
22 | ### Step 1: Download zipkin-server jar
23 | Download the [latest released server](https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=2.12.9&c=exec) as zipkin.jar:
24 |
25 | ```
26 | cd /tmp
27 | wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=2.12.9&c=exec'
28 | ```
29 |
30 | ### Step 2: Download the latest zipkin-storage-scouter jar
31 | Download the [latest released Scouter module](https://search.maven.org/remote_content?g=io.github.scouter-project&a=zipkin-autoconfigure-storage-scouter-udp&v=LATEST&c=module) as zipkin-storage-scouter.jar:
32 |
33 | ```
34 | cd /tmp
35 | wget -O zipkin-storage-scouter.jar 'https://search.maven.org/remote_content?g=io.github.scouter-project&a=zipkin-autoconfigure-storage-scouter-udp&v=LATEST&c=module'
36 | ```
37 |
38 | ### Step 3: Run the server with the "scouter" profile active
39 | When you enable the "scouter" profile, you can configure scouter with
40 | short environment variables similar to other [Zipkin integrations](https://github.com/openzipkin/zipkin/blob/master/zipkin-server/README.md#elasticsearch-storage).
41 |
42 | ``` bash
43 | cd /tmp
44 | SCOUTER_COLLECTOR_ADDR=127.0.0.1 \
45 | SCOUTER_COLLECTOR_PORT=6100 \
46 | SCOUTER_SERVICE_MAPS_OJB_TYPE= \
47 | STORAGE_TYPE=scouter \
48 | java -Dloader.path='zipkin-storage-scouter.jar,zipkin-storage-scouter.jar!lib' -Dspring.profiles.active=scouter -cp zipkin.jar org.springframework.boot.loader.PropertiesLauncher
49 | ```
50 | * **NOTE:** Make sure the parameters are defined in the same line or use environment variables **
51 |
52 | * Configures
53 | * `STORAGE_TYPE=scouter` : **required**. All others are optional.
54 | * `SCOUTER_COLLECTOR_ADDR` (default: 127.0.0.1) : Scouter collector IP
55 | * `SCOUTER_COLLECTOR_PORT` (default: 6100) : Scounter collector Port
56 | * `SCOUTER_UDP_PACKET_MAX_BYTES` (default: 60000) : should be smaller than OS UDP diagram size.
57 | * `SCOUTER_TAG_MAP_TEXT1` : tag mapping to scouter xlog's predefined column `text1` (default: `spring.instance_id`) (comma separated multi-tags supported.)
58 | * `SCOUTER_TAG_MAP_TEXT2` : tag mapping to scouter xlog's predefined column `text2` (comma separated multi-tags supported.)
59 | * `SCOUTER_TAG_MAP_TEXT3` : tag mapping to scouter xlog's predefined column `text3` (comma separated multi-tags supported.)
60 | * `SCOUTER_TAG_MAP_TEXT4` : tag mapping to scouter xlog's predefined column `text4` (comma separated multi-tags supported.)
61 | * `SCOUTER_TAG_MAP_TEXT5` : tag mapping to scouter xlog's predefined column `text5` (comma separated multi-tags supported.)
62 | * `SCOUTER_TAG_MAP_LOGIN` : tag mapping to scouter xlog's predefined dictionary encoded column `login` (just single first matching tag of comma separated tags is used for the column.)
63 | * `SCOUTER_TAG_MAP_DESC` : tag mapping to scouter xlog's predefined dictionary encoded column `desc` (just single first matching tag of comma separated tags is used for the column.)
64 | * `SCOUTER_SERVICE_MAPS_OJB_TYPE` : map a zipkin's local endpoint service name to a scouter objType (ex: system1:OrderSystem,system2:CustomerSystem ...). It use the same name of service name with preceding $z.
65 | * `SCOUTER_DEBUG` (default: false) : Debug option
66 |
67 | ### Limitation
68 | This currently only supports sending to a Scouter collector, not reading back spans from the service.
69 | Spans can be shown in the Scouter's XLog view.
70 |
71 | ### Scouter Links
72 | - [Scouter GitHub](https://github.com/scouter-project/scouter)
73 |
74 | ### Scouter Paper Links
75 | - [Scouter Paper Homepage](https://github.com/scouter-project/scouter)
76 | - **Scouter Paper showcase** : [scouter paper overview (youtube)](https://www.youtube.com/watch?v=NjJ0dGhdIbU)
77 |
78 |
--------------------------------------------------------------------------------
/autoconfigure/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 | 4.0.0
20 |
21 |
22 | io.github.scouter-project
23 | zipkin-scouter-parent
24 | 1.2.0
25 |
26 |
27 | zipkin-autoconfigure-scouter
28 | pom
29 |
30 | Zipkin Scouter Autoconfigure(Parent)
31 | Zipkin Scouter Autoconfigure(Parent)
32 | https://github.com/scouter-project/zipkin-scouter
33 |
34 |
35 | ${project.basedir}/..
36 |
37 | 1.8
38 | java18
39 |
40 |
41 |
42 | storage-scouter-udp-conf
43 |
44 |
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-autoconfigure
49 | ${spring-boot.version}
50 | provided
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-test
55 | ${spring-boot.version}
56 | test
57 |
58 |
59 |
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-maven-plugin
65 |
66 |
67 |
68 | io.zipkin.zipkin2,io.zipkin.reporter2,org.springframework.boot,org.springframework,com.fasterxml.jackson.core,com.google.auto.value,com.google.guava
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/autoconfigure/storage-scouter-udp-conf/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 | 4.0.0
20 |
21 |
22 | io.github.scouter-project
23 | zipkin-autoconfigure-scouter
24 | 1.2.0
25 |
26 |
27 | zipkin-autoconfigure-storage-scouter-udp
28 | Auto Configuration: Scouter UDP
29 |
30 |
31 | ${project.basedir}/../..
32 |
33 |
34 |
35 |
36 | io.github.scouter-project
37 | zipkin-storage-scouter-udp
38 |
39 |
40 |
41 |
42 |
43 |
44 | true
45 | src/main/resources
46 |
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-compiler-plugin
52 | 3.1
53 |
54 | 1.8
55 | 1.8
56 |
57 |
58 |
59 | org.apache.maven.plugins
60 | maven-jar-plugin
61 | 3.0.2
62 |
63 |
64 | maven-assembly-plugin
65 |
66 |
67 | package
68 |
69 | single
70 |
71 |
72 |
73 |
74 | zipkin-storage-scouter
75 | false
76 |
77 | jar-with-dependencies
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/autoconfigure/storage-scouter-udp-conf/src/main/java/zipkin/autoconfigure/storage/scouter/ZipkinScouterStorageAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2018 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | package zipkin.autoconfigure.storage.scouter;
20 |
21 | import org.springframework.beans.factory.annotation.Value;
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
24 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
25 | import org.springframework.context.annotation.Bean;
26 | import org.springframework.context.annotation.Configuration;
27 | import zipkin2.storage.StorageComponent;
28 |
29 | @Configuration
30 | @EnableConfigurationProperties(ZipkinScouterStorageProperties.class)
31 | @ConditionalOnProperty(name = "zipkin.storage.type", havingValue = "scouter")
32 | @ConditionalOnMissingBean(StorageComponent.class)
33 | public class ZipkinScouterStorageAutoConfiguration {
34 |
35 | @Bean
36 | @ConditionalOnMissingBean
37 | StorageComponent storage(ZipkinScouterStorageProperties properties,
38 | @Value("${zipkin.storage.strict-trace-id:true}") boolean strictTraceId) {
39 |
40 | return properties.toBuilder().strictTraceId(strictTraceId).build();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/autoconfigure/storage-scouter-udp-conf/src/main/java/zipkin/autoconfigure/storage/scouter/ZipkinScouterStorageProperties.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2018 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | package zipkin.autoconfigure.storage.scouter;
20 |
21 | import org.springframework.boot.context.properties.ConfigurationProperties;
22 | import zipkin2.storage.scouter.udp.ScouterConfig;
23 | import zipkin2.storage.scouter.udp.ScouterUDPStorage;
24 |
25 | import java.io.Serializable;
26 | import java.util.Map;
27 | import java.util.logging.Logger;
28 |
29 | @ConfigurationProperties("zipkin.storage.scouter")
30 | public class ZipkinScouterStorageProperties implements Serializable {
31 | private static final long serialVersionUID = 0L;
32 | private static final Logger logger = Logger.getLogger(ZipkinScouterStorageProperties.class.getName());
33 |
34 | /**
35 | * Scouter Collector UDP address; defaults to localhost:6100
36 | */
37 | private boolean debug;
38 | private String scouterCollectorAddress;
39 | private int scouterCollectorPort;
40 | private int scouterUdpPacketMaxBytes;
41 | private Map tagMap;
42 | private String serviceMapsToObjType;
43 |
44 | public boolean isDebug() {
45 | return debug;
46 | }
47 | public void setDebug(boolean debug) {
48 | this.debug = debug;
49 | }
50 |
51 | public String getScouterCollectorAddress() {
52 | return scouterCollectorAddress;
53 | }
54 | public void setScouterCollectorAddress(String scouterCollectorAddress) {
55 | this.scouterCollectorAddress = scouterCollectorAddress;
56 | }
57 |
58 | public int getScouterCollectorPort() {
59 | return scouterCollectorPort;
60 | }
61 | public void setScouterCollectorPort(int scouterCollectorPort) {
62 | this.scouterCollectorPort = scouterCollectorPort;
63 | }
64 |
65 | public int getScouterUdpPacketMaxBytes() {
66 | return scouterUdpPacketMaxBytes;
67 | }
68 | public void setScouterUdpPacketMaxBytes(int scouterUdpPacketMaxBytes) {
69 | this.scouterUdpPacketMaxBytes = scouterUdpPacketMaxBytes;
70 | }
71 |
72 | public Map getTagMap() {
73 | return tagMap;
74 | }
75 |
76 | public void setTagMap(Map tagMap) {
77 | this.tagMap = tagMap;
78 | }
79 |
80 | public String getServiceMapsToObjType() {
81 | return serviceMapsToObjType;
82 | }
83 |
84 | public void setServiceMapsToObjType(String serviceMapsToObjType) {
85 | this.serviceMapsToObjType = serviceMapsToObjType;
86 | }
87 |
88 | public ScouterUDPStorage.Builder toBuilder() {
89 | logger.info("[zipkin-scouter-storage] loading.");
90 | ScouterConfig config = new ScouterConfig(debug, scouterCollectorAddress, scouterCollectorPort, scouterUdpPacketMaxBytes, tagMap, serviceMapsToObjType);
91 | logger.info("[zipkin-scouter-storage] config " + config.toString());
92 | ScouterUDPStorage.Builder builder = ScouterUDPStorage.newBuilder();
93 | if (scouterCollectorAddress != null) builder.config(config);
94 | return builder;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/autoconfigure/storage-scouter-udp-conf/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | zipkin.autoconfigure.storage.scouter.ZipkinScouterStorageAutoConfiguration
3 |
--------------------------------------------------------------------------------
/autoconfigure/storage-scouter-udp-conf/src/main/resources/zipkin-server-scouter.yml:
--------------------------------------------------------------------------------
1 | # When enabled, this allows shorter env properties (ex -Dspring.profiles.active=scouter)
2 | zipkin:
3 | storage:
4 | scouter:
5 | debug: ${SCOUTER_DEBUG:false}
6 | # Scouter collector address
7 | scouter-collector-address: ${SCOUTER_COLLECTOR_ADDR:127.0.0.1}
8 | # Scouter collector port
9 | scouter-collector-port: ${SCOUTER_COLLECTOR_PORT:6100}
10 | scouter-udp-packet-max-bytes: ${SCOUTER_UDP_PACKET_MAX_BYTES:60000}
11 | tag-map:
12 | # tag mapping from zipkin to scouter xlog column. (comma separated multi-tags supported.)
13 | text1: ${SCOUTER_TAG_MAP_TEXT1:spring.instance_id}
14 | text2: ${SCOUTER_TAG_MAP_TEXT2:}
15 | text3: ${SCOUTER_TAG_MAP_TEXT3:}
16 | text4: ${SCOUTER_TAG_MAP_TEXT4:}
17 | text5: ${SCOUTER_TAG_MAP_TEXT5:}
18 | # tag mapping from zipkin to scouter xlog dictionary encoded column(login or desc). (just single first matching tag of comma separated tags is used for the column.)
19 | login: ${SCOUTER_TAG_MAP_LOGIN:}
20 | desc: ${SCOUTER_TAG_MAP_DESC:}
21 | # map a service to scouter objType (ex: system1:system1,system2:system2 ...). default use the same name of the zipkin local endpoint service name with preceding $z.
22 | service-maps-to-obj-type: ${SCOUTER_SERVICE_MAPS_OJB_TYPE:}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | io.github.scouter-project
8 | zipkin-scouter-parent
9 | 1.2.0
10 | pom
11 |
12 | Zipkin Scouter (Parent)
13 | Zipkin Scouter (Parent)
14 | https://github.com/scouter-project/zipkin-scouter
15 |
16 |
17 | storage-scouter-udp
18 | autoconfigure
19 |
20 |
21 |
22 |
23 | The Apache Software License, Version 2.0
24 | http://www.apache.org/licenses/LICENSE-2.0.txt
25 | repo
26 | A business-friendly OSS license
27 |
28 |
29 |
30 |
31 |
32 | gunlee01
33 | Gunhee Lee
34 | gunlee01@gmail.com
35 | https://github.com/gunlee01
36 |
37 | PMC
38 | developer
39 |
40 | +8
41 |
42 |
43 |
44 |
45 | github.com
46 | https://github.com/scouter-project/zipkin-scouter/issues
47 |
48 |
49 |
50 | scm:git:git@github.com:scouter-project/zipkin-scouter.git
51 | scm:git:git@github.com:scouter-project/zipkin-scouter.git
52 | git@github.com:scouter-project/zipkin-scouter.git
53 | HEAD
54 |
55 |
56 |
57 | UTF-8
58 | UTF-8
59 |
60 | 1.8
61 | java18
62 | ${project.basedir}
63 |
64 | 2.11.7
65 | 1.7.25
66 | 2.11.1
67 |
68 | 2.0.5.RELEASE
69 | 2.5.0
70 |
71 |
72 |
73 |
74 | ossrh
75 | https://oss.sonatype.org/content/repositories/snapshots
76 |
77 |
78 | ossrh
79 | https://oss.sonatype.org/service/local/staging/deploy/maven2
80 |
81 |
82 |
83 |
84 |
85 |
86 | io.zipkin.zipkin2
87 | zipkin
88 | ${zipkin.version}
89 |
90 |
91 | io.zipkin.zipkin2
92 | zipkin-collector
93 | ${zipkin.version}
94 |
95 |
96 | io.github.scouter-project
97 | scouter-common
98 | ${scouter.version}
99 |
100 |
101 | io.github.scouter-project
102 | zipkin-storage-scouter-udp
103 | ${project.version}
104 |
105 |
106 | io.github.scouter-project
107 | zipkin-autoconfigure-scouter
108 | ${project.version}
109 |
110 |
111 | io.github.scouter-project
112 | zipkin-autoconfigure-storage-scouter-udp
113 | ${project.version}
114 |
115 |
116 | junit
117 | junit
118 | 4.13.1
119 |
120 |
121 |
122 |
123 |
124 |
125 | io.github.scouter-project
126 | scouter-common
127 |
128 |
129 | io.zipkin.zipkin2
130 | zipkin
131 |
132 |
133 | junit
134 | junit
135 | test
136 |
137 |
138 | org.assertj
139 | assertj-core
140 | 3.11.1
141 | test
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | org.springframework.boot
150 | spring-boot-maven-plugin
151 | ${spring-boot.version}
152 |
153 |
154 |
155 | repackage
156 |
157 |
158 |
159 |
160 |
161 | zipkin
162 |
163 | module
164 |
165 |
166 |
167 | io.zipkin.layout
168 | zipkin-layout-factory
169 | 0.0.2
170 |
171 |
172 |
173 |
174 | org.apache.maven.plugins
175 | maven-source-plugin
176 | 3.0.1
177 |
178 |
179 | attach-sources
180 |
181 | jar-no-fork
182 |
183 |
184 |
185 |
186 |
187 | org.apache.maven.plugins
188 | maven-javadoc-plugin
189 |
190 | -Xdoclint:none
191 |
192 |
193 |
194 | attach-javadocs
195 |
196 | jar
197 |
198 |
199 |
200 |
201 |
202 | org.sonatype.plugins
203 | nexus-staging-maven-plugin
204 | 1.6.7
205 | true
206 |
207 | ossrh
208 | https://oss.sonatype.org/
209 | true
210 |
211 |
212 |
213 | org.apache.maven.plugins
214 | maven-gpg-plugin
215 | 1.5
216 |
217 |
218 | sign-artifacts
219 | verify
220 |
221 | sign
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 | org.apache.maven.plugins
231 | maven-source-plugin
232 |
233 |
234 | org.apache.maven.plugins
235 | maven-javadoc-plugin
236 |
237 |
238 | org.sonatype.plugins
239 | nexus-staging-maven-plugin
240 |
241 |
242 | org.apache.maven.plugins
243 | maven-gpg-plugin
244 |
245 |
246 |
247 |
248 |
249 |
--------------------------------------------------------------------------------
/storage-scouter-udp/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
19 | 4.0.0
20 |
21 |
22 | io.github.scouter-project
23 | zipkin-scouter-parent
24 | 1.2.0
25 |
26 |
27 | zipkin-storage-scouter-udp
28 | Zipkin Storage: Scouter UDP
29 |
30 |
31 | ${project.basedir}/..
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | src/main/resources
42 | true
43 |
44 |
45 |
46 |
47 | org.apache.maven.plugins
48 | maven-compiler-plugin
49 | 3.1
50 |
51 | 1.8
52 | 1.8
53 |
54 |
55 |
56 | org.apache.maven.plugins
57 | maven-jar-plugin
58 | 3.0.2
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/ScouterConstants.java:
--------------------------------------------------------------------------------
1 | package zipkin2.storage.scouter;
2 |
3 | import scouter.util.StringUtil;
4 | import zipkin2.storage.scouter.udp.ScouterConfig;
5 |
6 | import java.util.Map;
7 |
8 | /**
9 | * @author Gun Lee (gunlee01@gmail.com) on 31/10/2018
10 | */
11 | public class ScouterConstants {
12 | public static final String OBJ_PREFIX = "ZIPKIN/";
13 | public static final String OBJ_TYPE_PREFIX = "z$";
14 | public static final String UNKNOWN = "UNKNOWN";
15 |
16 | public static String toScouterObjName(String name) {
17 | if (StringUtil.isNotEmpty(name)) {
18 | return OBJ_PREFIX + name;
19 | } else {
20 | return OBJ_PREFIX + UNKNOWN;
21 | }
22 | }
23 |
24 | public static String toScouterObjType(String name, ScouterConfig conf) {
25 | if (StringUtil.isNotEmpty(name)) {
26 | Map serviceToType = conf.getServiceToObjTypeMap();
27 | return OBJ_TYPE_PREFIX + serviceToType.getOrDefault(name, name);
28 | } else {
29 | return "zipkin";
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/udp/ScouterConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2018 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | package zipkin2.storage.scouter.udp;
20 |
21 | import scouter.util.StringUtil;
22 |
23 | import java.util.HashMap;
24 | import java.util.Map;
25 | import java.util.stream.Stream;
26 |
27 | import static java.util.stream.Collectors.toMap;
28 |
29 | public final class ScouterConfig {
30 | boolean debug;
31 | String address;
32 | int port;
33 | int udpPacketMaxBytes;
34 | String loginTag;
35 | String descTag;
36 | String text1Tag;
37 | String text2Tag;
38 | String text3Tag;
39 | String text4Tag;
40 | String text5Tag;
41 | Map seviceToObjTypeMap = new HashMap<>();
42 |
43 | public ScouterConfig(boolean debug, String address, int port, int udpPacketMaxBytes,
44 | Map tagMap, String serviceMapsToObjType) {
45 | this.debug = debug;
46 | this.address = address;
47 | this.port = port;
48 | this.udpPacketMaxBytes = udpPacketMaxBytes;
49 | this.loginTag = tagMap.get("login");
50 | this.descTag = tagMap.get("desc");
51 | this.text1Tag = tagMap.get("text1");
52 | this.text2Tag = tagMap.get("text2");
53 | this.text3Tag = tagMap.get("text3");
54 | this.text4Tag = tagMap.get("text4");
55 | this.text5Tag = tagMap.get("text5");
56 |
57 | if (StringUtil.isNotEmpty(serviceMapsToObjType)) {
58 | seviceToObjTypeMap = Stream.of(serviceMapsToObjType.split(","))
59 | .map(str -> str.split(":"))
60 | .collect(toMap(kv -> kv[0], kv -> kv[1]));
61 | }
62 | }
63 |
64 | public boolean isDebug() {
65 | return debug;
66 | }
67 |
68 | public String getAddress() {
69 | return address;
70 | }
71 |
72 | public int getPort() {
73 | return port;
74 | }
75 |
76 | public int getUdpPacketMaxBytes() {
77 | return udpPacketMaxBytes;
78 | }
79 |
80 | public Map getServiceToObjTypeMap() {
81 | return seviceToObjTypeMap;
82 | }
83 |
84 | public String getLoginTag() {
85 | return loginTag;
86 | }
87 |
88 | public String getDescTag() {
89 | return descTag;
90 | }
91 |
92 | public String getText1Tag() {
93 | return text1Tag;
94 | }
95 |
96 | public String getText2Tag() {
97 | return text2Tag;
98 | }
99 |
100 | public String getText3Tag() {
101 | return text3Tag;
102 | }
103 |
104 | public String getText4Tag() {
105 | return text4Tag;
106 | }
107 |
108 | public String getText5Tag() {
109 | return text5Tag;
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return "ScouterConfig{" +
115 | "address='" + address + '\'' +
116 | ", port=" + port +
117 | ", udpPacketMaxBytes=" + udpPacketMaxBytes +
118 | ", debug=" + debug +
119 | ", loginTag='" + loginTag + '\'' +
120 | ", descTag='" + descTag + '\'' +
121 | ", text1Tag='" + text1Tag + '\'' +
122 | ", text2Tag='" + text2Tag + '\'' +
123 | ", text3Tag='" + text3Tag + '\'' +
124 | ", text4Tag='" + text4Tag + '\'' +
125 | ", text5Tag='" + text5Tag + '\'' +
126 | ", seviceToObjTypeMap=" + seviceToObjTypeMap +
127 | '}';
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/udp/ScouterUDPStorage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-2018 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | package zipkin2.storage.scouter.udp;
20 |
21 | import zipkin2.Call;
22 | import zipkin2.Callback;
23 | import zipkin2.DependencyLink;
24 | import zipkin2.Span;
25 | import zipkin2.storage.QueryRequest;
26 | import zipkin2.storage.SpanConsumer;
27 | import zipkin2.storage.SpanStore;
28 | import zipkin2.storage.StorageComponent;
29 | import zipkin2.storage.scouter.udp.net.DataProxy;
30 |
31 | import java.io.IOException;
32 | import java.net.DatagramSocket;
33 | import java.util.HashMap;
34 | import java.util.List;
35 | import java.util.logging.Level;
36 | import java.util.logging.Logger;
37 |
38 | public final class ScouterUDPStorage extends StorageComponent implements SpanStore, SpanConsumer {
39 | private static final Logger logger = Logger.getLogger(ScouterUDPStorage.class.getName());
40 | private static ScouterConfig config;
41 |
42 | public static Builder newBuilder() {
43 | return new Builder();
44 | }
45 |
46 | private volatile DatagramSocket socket;
47 | private volatile boolean closeCalled;
48 |
49 | private ScouterUDPStorage(ScouterConfig config) {
50 | this.config = config;
51 | }
52 |
53 | public static ScouterConfig getConfig() {
54 | return config;
55 | }
56 |
57 | @Override
58 | public SpanStore spanStore() {
59 | return this;
60 | }
61 |
62 | @Override
63 | public SpanConsumer spanConsumer() {
64 | return this;
65 | }
66 |
67 | @Override
68 | public Call accept(List spans) {
69 | if (config.isDebug()) {
70 | logger.info("SPANS received : " + spans);
71 | }
72 | if (closeCalled) throw new IllegalStateException("closed");
73 | if (spans.isEmpty()) return Call.create(null);
74 | return new UDPCall(spans);
75 | }
76 |
77 | @Override
78 | public synchronized void close() {
79 | if (closeCalled) return;
80 | DatagramSocket socket = this.socket;
81 | if (socket != null) socket.close();
82 | closeCalled = true;
83 | }
84 |
85 | @Override
86 | public Call>> getTraces(QueryRequest queryRequest) {
87 | throw new UnsupportedOperationException("This is collector-only at the moment");
88 | }
89 |
90 | @Override
91 | public Call> getTrace(String s) {
92 | throw new UnsupportedOperationException("This is collector-only at the moment");
93 | }
94 |
95 | @Override
96 | public Call> getServiceNames() {
97 | throw new UnsupportedOperationException("This is collector-only at the moment");
98 | }
99 |
100 | @Override
101 | public Call> getSpanNames(String s) {
102 | throw new UnsupportedOperationException("This is collector-only at the moment");
103 | }
104 |
105 | @Override
106 | public Call> getDependencies(long l, long l1) {
107 | throw new UnsupportedOperationException("This is collector-only at the moment");
108 | }
109 |
110 | public static final class Builder extends StorageComponent.Builder {
111 | ScouterConfig config;
112 |
113 | /**
114 | * Ignored as Scouter doesn't accept 64-bit trace IDs. downgrade the ID in scouter.
115 | */
116 | @Override
117 | public Builder strictTraceId(boolean strictTraceId) {
118 | return this;
119 | }
120 |
121 | /**
122 | * Ignored as Scouter doesn't expose storage options
123 | */
124 | @Override
125 | public Builder searchEnabled(boolean searchEnabled) {
126 | return this;
127 | }
128 |
129 | /**
130 | * Defaults to the env variable
131 | */
132 | public Builder config(ScouterConfig config) {
133 | if (config == null) throw new IllegalArgumentException("config == null");
134 | this.config = config;
135 | return this;
136 | }
137 |
138 | @Override
139 | public ScouterUDPStorage build() {
140 | if (config == null) {
141 | config = new ScouterConfig(false, "127.0.0.1", 6100, 60000, new HashMap<>(), null);
142 | }
143 |
144 | return new ScouterUDPStorage(config);
145 | }
146 |
147 | Builder() {
148 | }
149 | }
150 |
151 | @Override
152 | public final String toString() {
153 | return "ScouterUDPStorage{address=" + config.getAddress() + ":" + config.getPort() + "}";
154 | }
155 |
156 |
157 | static class UDPCall extends Call.Base {
158 | private static final Logger logger = Logger.getLogger(UDPCall.class.getName());
159 | private final List spans;
160 |
161 | UDPCall(List spans) {
162 | this.spans = spans;
163 | }
164 |
165 | @Override
166 | protected Void doExecute() throws IOException {
167 | DataProxy.sendSpanContainer(spans, config);
168 | return null;
169 | }
170 |
171 | @Override
172 | protected void doEnqueue(Callback callback) {
173 | try {
174 | doExecute();
175 | callback.onSuccess(null);
176 |
177 | } catch (IOException | RuntimeException | Error e) {
178 | logger.log(Level.WARNING, e.getMessage(), e);
179 | propagateIfFatal(e);
180 | callback.onError(e);
181 | }
182 | }
183 |
184 | @Override
185 | public Call clone() {
186 | return new UDPCall(spans);
187 | }
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/udp/net/DataProxy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package zipkin2.storage.scouter.udp.net;
18 |
19 | import scouter.io.DataOutputX;
20 | import scouter.lang.TextTypes;
21 | import scouter.lang.pack.ObjectPack;
22 | import scouter.lang.pack.Pack;
23 | import scouter.lang.pack.SpanContainerPack;
24 | import scouter.lang.pack.SpanPack;
25 | import scouter.lang.pack.SpanTypes;
26 | import scouter.lang.pack.TextPack;
27 | import scouter.lang.pack.XLogPack;
28 | import scouter.lang.pack.XLogTypes;
29 | import scouter.lang.value.ListValue;
30 | import scouter.lang.value.MapValue;
31 | import scouter.util.HashUtil;
32 | import scouter.util.IntIntLinkedMap;
33 | import scouter.util.IntLinkedSet;
34 | import scouter.util.IntLongLinkedMap;
35 | import scouter.util.StringUtil;
36 | import zipkin2.Annotation;
37 | import zipkin2.Endpoint;
38 | import zipkin2.Span;
39 | import zipkin2.internal.HexCodec;
40 | import zipkin2.storage.scouter.ScouterConstants;
41 | import zipkin2.storage.scouter.udp.ScouterConfig;
42 |
43 | import java.io.IOException;
44 | import java.util.Arrays;
45 | import java.util.List;
46 | import java.util.Map;
47 | import java.util.logging.Logger;
48 | import java.util.regex.Pattern;
49 | import java.util.stream.Collectors;
50 |
51 | public class DataProxy {
52 | private static final Logger logger = Logger.getLogger(DataProxy.class.getName());
53 | private static UDPDataSendThread udpCollect = UDPDataSendThread.getInstance();
54 | private static IntIntLinkedMap sqlHash = new IntIntLinkedMap().setMax(5000);
55 | private static final Pattern WHITE_SPACE = Pattern.compile("\\s\\s+");
56 |
57 | private static int getSqlHash(String sql) {
58 | if (sql.length() < 100)
59 | return HashUtil.hash(sql);
60 | int id = sql.hashCode();
61 | int hash = sqlHash.get(id);
62 | if (hash == 0) {
63 | hash = HashUtil.hash(sql);
64 | sqlHash.put(id, hash);
65 | }
66 | return hash;
67 | }
68 |
69 | private static IntLinkedSet sqlText = new IntLinkedSet().setMax(10000);
70 |
71 | public static int sendSqlText(String sql) {
72 | int hash = getSqlHash(sql);
73 | if (sqlText.contains(hash)) {
74 | return hash;
75 | }
76 | sqlText.put(hash);
77 | sendDirect(new TextPack(TextTypes.SQL, hash, sql));
78 | return hash;
79 | }
80 |
81 | private static IntLinkedSet serviceName = new IntLinkedSet().setMax(10000);
82 |
83 | public static int sendServiceName(String service) {
84 | int hash = HashUtil.hash(service);
85 | sendServiceName(hash, service);
86 | return hash;
87 | }
88 |
89 | public static void sendServiceName(int hash, String service) {
90 | if (serviceName.contains(hash)) {
91 | return;
92 | }
93 | serviceName.put(hash);
94 | udpCollect.add(new TextPack(TextTypes.SERVICE, hash, service));
95 | }
96 |
97 | private static IntLinkedSet descTable = new IntLinkedSet().setMax(1000);
98 |
99 | public static int sendDesc(String desc) {
100 | int hash = HashUtil.hash(desc);
101 | if (descTable.contains(hash)) {
102 | return hash;
103 | }
104 | descTable.put(hash);
105 | udpCollect.add(new TextPack(TextTypes.DESC, hash, desc));
106 | return hash;
107 | }
108 |
109 | private static IntLinkedSet loginTable = new IntLinkedSet().setMax(10000);
110 |
111 | public static int sendLogin(String loginName) {
112 | int hash = HashUtil.hash(loginName);
113 | if (loginTable.contains(hash)) {
114 | return hash;
115 | }
116 | loginTable.put(hash);
117 | udpCollect.add(new TextPack(TextTypes.LOGIN, hash, loginName));
118 | return hash;
119 | }
120 |
121 | private static IntLinkedSet objNameSet = new IntLinkedSet().setMax(10000);
122 |
123 | private static IntLongLinkedMap objSentMap = new IntLongLinkedMap().setMax(1000);
124 |
125 | public static void registerZipkinObj(Span span, ScouterConfig conf) {
126 | String objName = ScouterConstants.toScouterObjName(span.localServiceName());
127 | int objHash = HashUtil.hash(objName);
128 |
129 | long registered = objSentMap.get(objHash);
130 | long now = System.currentTimeMillis();
131 | if (registered != 0 && now - registered < 30 * 1000) {
132 | return;
133 | }
134 |
135 | ObjectPack p = new ObjectPack();
136 | p.objType = ScouterConstants.toScouterObjType(span.localServiceName(), conf);
137 | p.objName = objName;
138 | p.objHash = objHash;
139 | if (span.localEndpoint() != null) {
140 | p.address = span.localEndpoint().ipv4() + ":" + span.localEndpoint().portAsInt();
141 | }
142 | p.tags.put(scouter.lang.constants.ScouterConstants.TAG_OBJ_DETECTED_TYPE, "zipkin");
143 | p.tags.put(ObjectPack.TAG_KEY_DEAD_TIME, 300 * 1000);
144 |
145 | objSentMap.put(objHash, now);
146 | sendHeartBeat(p);
147 |
148 | if (conf.isDebug()) {
149 | logger.info("Object heartbeat: " + p);
150 | }
151 | }
152 |
153 | public static void sendHeartBeat(ObjectPack p) {
154 | udpCollect.add(p);
155 | }
156 |
157 | public static int sendObjName(String objName) {
158 | if (objName == null) {
159 | return 0;
160 | }
161 | int hash = HashUtil.hash(objName);
162 | sendObjName(hash, objName);
163 | return hash;
164 | }
165 |
166 | public static void sendObjName(int hash, String objName) {
167 | if (objName == null) {
168 | return;
169 | }
170 | if (objNameSet.contains(hash)) {
171 | return;
172 | }
173 | objNameSet.put(hash);
174 | udpCollect.add(new TextPack(TextTypes.OBJECT, hash, objName));
175 | }
176 |
177 | private static IntLinkedSet errText = new IntLinkedSet().setMax(10000);
178 |
179 | public static int sendError(String message) {
180 | int hash = HashUtil.hash(message);
181 | if (errText.contains(hash)) {
182 | return hash;
183 | }
184 | errText.put(hash);
185 | udpCollect.add(new TextPack(TextTypes.ERROR, hash, message));
186 | return hash;
187 | }
188 |
189 | private static IntLinkedSet hashMessage = new IntLinkedSet().setMax(10000);
190 |
191 | public static int sendHashedMessage(String text) {
192 | int hash = HashUtil.hash(text);
193 | if (hashMessage.contains(hash)) {
194 | return hash;
195 | }
196 | hashMessage.put(hash);
197 | udpCollect.add(new TextPack(TextTypes.HASH_MSG, hash, text));
198 | return hash;
199 | }
200 |
201 | public static void reset() {
202 | serviceName.clear();
203 | errText.clear();
204 | sqlText.clear();
205 | hashMessage.clear();
206 | }
207 |
208 | public static void sendXLog(XLogPack p) {
209 | sendDirect(p);
210 | }
211 |
212 | static DataUdpAgent udpNet = DataUdpAgent.getInstance();
213 |
214 | public static void sendDirect(Pack p) {
215 | try {
216 | udpNet.write(new DataOutputX().writePack(p).toByteArray());
217 | } catch (IOException e) {
218 | }
219 | }
220 |
221 | private static void sendDirect(List buff) {
222 | switch (buff.size()) {
223 | case 0:
224 | return;
225 | case 1:
226 | udpNet.write(buff.get(0));
227 | break;
228 | default:
229 | udpNet.write(buff);
230 | break;
231 | }
232 | }
233 |
234 | public static void sendSpanContainer(final List spans, final ScouterConfig conf) {
235 | int udpMaxBytes = conf.getUdpPacketMaxBytes();
236 | if (spans == null || spans.size() == 0)
237 | return;
238 |
239 | Map> spansById = spans.stream()
240 | .collect(Collectors.groupingBy(Span::traceId));
241 |
242 | for (Map.Entry> entry : spansById.entrySet()) {
243 | SpanContainerPack containerPack = new SpanContainerPack();
244 | containerPack.gxid = HexCodec.lowerHexToUnsignedLong(entry.getKey());
245 | containerPack.spanCount = entry.getValue().size();
246 |
247 | List spanList = entry.getValue();
248 | spanList.forEach(span -> DataProxy.registerZipkinObj(span, conf));
249 |
250 | List spanPacks = spanList.stream()
251 | .map(DataProxy::makeSpanPack).collect(Collectors.toList());
252 |
253 | if (conf.isDebug()) {
254 | spanPacks.forEach(pack -> logger.info("SpanPack generated: " + pack.toString()));
255 | }
256 |
257 | List spansBytesList = SpanPack.toBytesList(spanPacks, udpMaxBytes);
258 | for (byte[] spansBytes : spansBytesList) {
259 | containerPack.spans = spansBytes;
260 | sendDirect(containerPack);
261 | }
262 |
263 | for (SpanPack spanPack : spanPacks) {
264 | if (SpanTypes.isXLoggable(spanPack.spanType)) {
265 | XLogPack xlogPack = makeXLogPack(spanPack, conf);
266 | if (conf.isDebug()) {
267 | logger.info("XLog generated: " + xlogPack);
268 | }
269 | sendXLog(xlogPack);
270 | }
271 | }
272 | }
273 | }
274 |
275 | private static SpanPack makeSpanPack(Span span) {
276 | SpanPack pack = new SpanPack();
277 |
278 | pack.gxid = HexCodec.lowerHexToUnsignedLong(span.traceId());
279 | pack.txid = HexCodec.lowerHexToUnsignedLong(span.id());
280 | pack.caller = span.parentId() != null ? HexCodec.lowerHexToUnsignedLong(span.parentId()) : 0L;
281 |
282 | pack.timestamp = span.timestampAsLong() / 1000;
283 | pack.elapsed = (int) (span.durationAsLong() / 1000);
284 |
285 | pack.spanType = SpanTypes.UNKNOWN;
286 | if (span.kind() != null) {
287 | switch (span.kind()) {
288 | case SERVER:
289 | pack.spanType = SpanTypes.SERVER;
290 | break;
291 | case CLIENT:
292 | pack.spanType = SpanTypes.CLIENT;
293 | break;
294 | case PRODUCER:
295 | pack.spanType = SpanTypes.PRODUCER;
296 | break;
297 | case CONSUMER:
298 | pack.spanType = SpanTypes.CONSUMER;
299 | break;
300 | }
301 | }
302 |
303 | String error = span.tags().get("error");
304 | if (StringUtil.isNotEmpty(error)) {
305 | pack.error = sendError(error);
306 | }
307 |
308 | Endpoint localEndPoint = span.localEndpoint();
309 | Endpoint remoteEndPoint = span.remoteEndpoint();
310 |
311 | pack.objHash = sendObjName(ScouterConstants.toScouterObjName(span.localServiceName()));
312 | pack.localEndpointServiceName = sendObjName(span.localServiceName());
313 | pack.remoteEndpointServiceName = sendObjName(span.remoteServiceName());
314 | pack.localEndpointIp = localEndPoint != null ? localEndPoint.ipv4Bytes() : null;
315 | pack.remoteEndpointIp = remoteEndPoint != null ? remoteEndPoint.ipv4Bytes() : null;
316 | pack.localEndpointPort = localEndPoint != null ? (short) localEndPoint.portAsInt() : 0;
317 | pack.remoteEndpointPort = remoteEndPoint != null ? (short) remoteEndPoint.portAsInt() : 0;
318 |
319 | Boolean spanDebug = span.debug();
320 | Boolean spanShared = span.shared();
321 | pack.debug = spanDebug != null ? spanDebug : false;
322 | pack.shared = spanShared != null ? spanShared : false;
323 |
324 | pack.annotationTimestamps = new ListValue();
325 | pack.annotationValues = new ListValue();
326 | for (Annotation annotation : span.annotations()) {
327 | pack.annotationTimestamps.add(annotation.timestamp() / 1000);
328 | pack.annotationValues.add(annotation.value());
329 | }
330 |
331 | pack.tags = MapValue.ofStringValueMap(span.tags());
332 |
333 | String serviceName = StringUtil.emptyToDefault(span.name(), "").trim();
334 | if (pack.spanType == SpanTypes.CLIENT) {
335 | if (pack.tags.getText("sql.query") != null) {
336 | //serviceName = pack.tags.getText("sql.query").replaceAll("[\r\n]+", " ");
337 | serviceName = WHITE_SPACE.matcher(pack.tags.getText("sql.query")).replaceAll(" ");
338 | } else if (pack.tags.getText("http.path") != null) {
339 | serviceName = pack.tags.getText("http.method") + " " + pack.tags.getText("http.path");
340 | }
341 | }
342 | pack.name = sendServiceName(serviceName);
343 |
344 | return pack;
345 | }
346 |
347 | public static XLogPack makeXLogPack(SpanPack pack, ScouterConfig conf) {
348 | XLogPack xlog = new XLogPack();
349 | xlog.endTime = pack.timestamp + pack.elapsed;
350 | xlog.objHash = pack.objHash;
351 | xlog.service = pack.name;
352 | xlog.txid = pack.txid;
353 | xlog.gxid = pack.gxid;
354 | xlog.caller = pack.caller;
355 | xlog.elapsed = pack.elapsed;
356 | xlog.error = pack.error;
357 | xlog.xType = XLogTypes.ZIPKIN_SPAN;
358 |
359 | String loginColumnString = map1stMatchingTagNames(pack, conf.getLoginTag());
360 | if (StringUtil.isNotEmpty(loginColumnString)) {
361 | xlog.login = sendLogin(loginColumnString);
362 | }
363 | String descColumnString = map1stMatchingTagNames(pack, conf.getDescTag());
364 | if (StringUtil.isNotEmpty(descColumnString)) {
365 | xlog.desc = sendLogin(descColumnString);
366 | }
367 |
368 | xlog.text1 = mapTagNames(pack, conf.getText1Tag());
369 | xlog.text2 = mapTagNames(pack, conf.getText2Tag());
370 | xlog.text3 = mapTagNames(pack, conf.getText3Tag());
371 | xlog.text4 = mapTagNames(pack, conf.getText4Tag());
372 | xlog.text5 = mapTagNames(pack, conf.getText5Tag());
373 |
374 | return xlog;
375 | }
376 |
377 | protected static String map1stMatchingTagNames(SpanPack pack, String tagNames) {
378 | if (StringUtil.isEmpty(tagNames)) {
379 | return null;
380 | }
381 | return Arrays.stream(tagNames.split(","))
382 | .map(tag -> pack.tags.getText(tag))
383 | .filter(StringUtil::isNotEmpty)
384 | .findFirst().orElse(null);
385 | }
386 |
387 | protected static String mapTagNames(SpanPack pack, String tagNames) {
388 | if (StringUtil.isEmpty(tagNames)) {
389 | return null;
390 | }
391 | return Arrays.stream(tagNames.split(","))
392 | .map(tag -> pack.tags.getText(tag))
393 | .filter(StringUtil::isNotEmpty)
394 | .collect(Collectors.joining(","));
395 | }
396 | }
397 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/udp/net/DataUdpAgent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | package zipkin2.storage.scouter.udp.net;
18 |
19 | import scouter.io.DataInputX;
20 | import scouter.io.DataOutputX;
21 | import scouter.net.NetCafe;
22 | import scouter.util.KeyGen;
23 | import zipkin2.storage.scouter.udp.ScouterConfig;
24 | import zipkin2.storage.scouter.udp.ScouterUDPStorage;
25 |
26 | import java.io.IOException;
27 | import java.net.DatagramPacket;
28 | import java.net.DatagramSocket;
29 | import java.net.InetAddress;
30 | import java.util.List;
31 | import java.util.logging.Level;
32 | import java.util.logging.Logger;
33 |
34 | public class DataUdpAgent {
35 | private static final Logger logger = Logger.getLogger(DataUdpAgent.class.getName());
36 | private static DataUdpAgent inst;
37 |
38 | InetAddress serverHost;
39 | int serverPort;
40 | private DatagramSocket datagram;
41 |
42 | private DataUdpAgent() {
43 | setTarget();
44 | openDatagramSocket();
45 | }
46 |
47 | private void setTarget() {
48 | ScouterConfig config = ScouterUDPStorage.getConfig();
49 | if (config != null) {
50 | String host = config.getAddress();
51 | int port = config.getPort();
52 | try {
53 | serverHost = InetAddress.getByName(host);
54 | serverPort = port;
55 | } catch (Exception e) {
56 | logger.log(Level.WARNING, e.getMessage(), e);
57 | }
58 | }
59 | }
60 | protected void close(DatagramSocket d) {
61 | if (d != null) {
62 | try {
63 | d.close();
64 | } catch (Exception e) {
65 | }
66 | }
67 | }
68 | private void openDatagramSocket() {
69 | try {
70 | datagram = new DatagramSocket();
71 | } catch (Exception e) {
72 | logger.log(Level.SEVERE, e.getMessage(), e);
73 | }
74 | }
75 |
76 | public static synchronized DataUdpAgent getInstance() {
77 | if (inst == null) {
78 | inst = new DataUdpAgent();
79 | }
80 | return inst;
81 | }
82 |
83 | ScouterConfig config = ScouterUDPStorage.getConfig();
84 |
85 | public boolean write(byte[] p) {
86 | try {
87 | if (serverHost == null)
88 | return false;
89 | if (p.length > config.getUdpPacketMaxBytes()) {
90 | return writeMTU(p, config.getUdpPacketMaxBytes());
91 | }
92 | DataOutputX out = new DataOutputX();
93 | out.write(NetCafe.CAFE);
94 | out.write(p);
95 | byte[] buff = out.toByteArray();
96 | DatagramPacket packet = new DatagramPacket(buff, buff.length);
97 | packet.setAddress(serverHost);
98 | packet.setPort(serverPort);
99 | datagram.send(packet);
100 | return true;
101 |
102 | } catch (IOException e) {
103 | logger.log(Level.WARNING, "A120: UDP writing error. " + e.getMessage());
104 | return false;
105 | }
106 | }
107 |
108 | private boolean writeMTU(byte[] data, int packetSize) {
109 | try {
110 | if (serverHost == null)
111 | return false;
112 | long pkid = KeyGen.next();
113 | int total = data.length / packetSize;
114 | int remainder = data.length % packetSize;
115 | if (remainder > 0)
116 | total++;
117 | int num = 0;
118 | for (num = 0; num < data.length / packetSize; num++) {
119 | writeMTU(pkid, total, num, packetSize, DataInputX.get(data, num * packetSize, packetSize));
120 | }
121 | if (remainder > 0) {
122 | writeMTU(pkid, total, num, remainder, DataInputX.get(data, data.length - remainder, remainder));
123 | }
124 | return true;
125 |
126 | } catch (IOException e) {
127 | logger.log(Level.WARNING, "A121: UDP writing error.(MTU) " + e.getMessage());
128 | return false;
129 | }
130 | }
131 |
132 | private void writeMTU(long pkid, int total, int num, int packetSize, byte[] data) throws IOException {
133 | DataOutputX out = new DataOutputX();
134 | out.write(NetCafe.CAFE_MTU);
135 | out.writeInt(0);
136 | out.writeLong(pkid);
137 | out.writeShort(total);
138 | out.writeShort(num);
139 | out.writeBlob(data);
140 | byte[] buff = out.toByteArray();
141 | DatagramPacket packet = new DatagramPacket(buff, buff.length);
142 | packet.setAddress(serverHost);
143 | packet.setPort(serverPort);
144 | datagram.send(packet);
145 | }
146 |
147 | public void close() {
148 | if (datagram != null)
149 | datagram.close();
150 | datagram = null;
151 | }
152 |
153 | public boolean write(List p) {
154 | try {
155 | if (serverHost == null)
156 | return false;
157 | DataOutputX buffer = new DataOutputX();
158 | int bufferCount = 0;
159 | for (int i = 0; i < p.size(); i++) {
160 | byte[] b = p.get(i);
161 | if (b.length > config.getUdpPacketMaxBytes()) {
162 | writeMTU(b, config.getUdpPacketMaxBytes());
163 |
164 | } else if (b.length + buffer.getWriteSize() > config.getUdpPacketMaxBytes()) {
165 | sendList(bufferCount, buffer.toByteArray());
166 | buffer = new DataOutputX();
167 | bufferCount = 1;
168 | buffer.write(b);
169 |
170 | } else {
171 | bufferCount++;
172 | buffer.write(b);
173 | }
174 | }
175 |
176 | if (buffer.getWriteSize() > 0) {
177 | sendList(bufferCount, buffer.toByteArray());
178 | }
179 | return true;
180 | } catch (IOException e) {
181 | logger.log(Level.WARNING, "A123: UDP writing error." + e.getMessage());
182 | return false;
183 | }
184 | }
185 |
186 | private void sendList(int bufferCount, byte[] buffer) throws IOException {
187 | DataOutputX outter = new DataOutputX();
188 | outter.write(NetCafe.CAFE_N);
189 | outter.writeShort(bufferCount);
190 | outter.write(buffer);
191 | byte[] buff = outter.toByteArray();
192 | DatagramPacket packet = new DatagramPacket(buff, buff.length);
193 | packet.setAddress(serverHost);
194 | packet.setPort(serverPort);
195 | datagram.send(packet);
196 | }
197 |
198 | public boolean debugWrite(String ip, int port, int length) {
199 | try {
200 | DataOutputX out = new DataOutputX();
201 | out.write("TEST".getBytes());
202 | if (length > 4) {
203 | out.write(new byte[length - 4]);
204 | }
205 | byte[] buff = out.toByteArray();
206 | DatagramPacket packet = new DatagramPacket(buff, buff.length);
207 | packet.setAddress(InetAddress.getByName(ip));
208 | packet.setPort(port);
209 | datagram.send(packet);
210 | logger.info( "A124: Sent " + length + " bytes to " + ip + ":" + port);
211 | return true;
212 |
213 | } catch (IOException e) {
214 | logger.info( "A124: Sent " + length + " bytes to " + ip + ":" + port);
215 |
216 | logger.log(Level.WARNING, "A125: UDP writing error.(MTU) " + e.getMessage());
217 | return false;
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/storage-scouter-udp/src/main/java/zipkin2/storage/scouter/udp/net/UDPDataSendThread.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 the original author or authors.
3 | * @https://github.com/scouter-project/scouter
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | package zipkin2.storage.scouter.udp.net;
19 |
20 | import scouter.io.DataOutputX;
21 | import scouter.lang.pack.Pack;
22 | import scouter.util.Queue;
23 | import scouter.util.ThreadUtil;
24 | import zipkin2.storage.scouter.udp.ScouterConfig;
25 | import zipkin2.storage.scouter.udp.ScouterUDPStorage;
26 |
27 | import java.util.ArrayList;
28 | import java.util.List;
29 |
30 | public class UDPDataSendThread extends Thread {
31 |
32 | private static UDPDataSendThread instance = null;
33 | ScouterConfig config = ScouterUDPStorage.getConfig();
34 |
35 | public final static synchronized UDPDataSendThread getInstance() {
36 | if (instance == null) {
37 | instance = new UDPDataSendThread();
38 | instance.setDaemon(true);
39 | instance.setName(ThreadUtil.getName(instance));
40 | instance.start();
41 | }
42 | return instance;
43 | }
44 |
45 | protected UDPDataSendThread() {
46 | }
47 |
48 | private Queue queue = new Queue(1024);
49 |
50 | public int getQueueSize() {
51 | return queue.size();
52 | }
53 |
54 | public boolean add(Pack p) {
55 | try {
56 | byte[] b = new DataOutputX().writePack(p).toByteArray();
57 | Object ok = queue.push(b);
58 | return ok != null;
59 | } catch (Exception e) {
60 | }
61 | return false;
62 | }
63 |
64 | public boolean isQueueOk() {
65 | return queue.size() < 1000;
66 | }
67 |
68 | public void shutdown() {
69 | running = false;
70 | }
71 |
72 | private boolean running = true;
73 |
74 | public void run() {
75 | DataUdpAgent udp = DataUdpAgent.getInstance();
76 |
77 | while (running) {
78 | int size = queue.size();
79 | switch (size) {
80 | case 0:
81 | ThreadUtil.sleep(100);
82 | break;
83 | case 1:
84 | udp.write(queue.pop());
85 | break;
86 | default:
87 | send(udp, size);
88 | break;
89 | }
90 |
91 | }
92 | }
93 |
94 | private void send(DataUdpAgent udp, int size) {
95 | List buff = new ArrayList();
96 | int bytes = 0;
97 | for (int k = 0; k < size; k++) {
98 | byte[] b = queue.pop();
99 | if (bytes + b.length >= config.getUdpPacketMaxBytes()) {
100 | send(udp, buff);
101 | bytes = 0;
102 | buff.clear();
103 | }
104 | bytes += b.length;
105 | buff.add(b);
106 | }
107 | send(udp, buff);
108 | }
109 |
110 | public void send(DataUdpAgent udp, List buff) {
111 | switch (buff.size()) {
112 | case 0:
113 | break;
114 | case 1:
115 | udp.write(buff.get(0));
116 | break;
117 | default:
118 | udp.write(buff);
119 | break;
120 | }
121 | }
122 |
123 | }
--------------------------------------------------------------------------------
/storage-scouter-udp/src/test/java/zipkin2/storage/scouter/ScouterConstantsTest.java:
--------------------------------------------------------------------------------
1 | package zipkin2.storage.scouter;
2 |
3 | import org.junit.Test;
4 | import zipkin2.storage.scouter.udp.ScouterConfig;
5 |
6 | import java.util.HashMap;
7 |
8 | import static org.junit.Assert.*;
9 |
10 | /**
11 | * @author Gun Lee (gunlee01@gmail.com) on 10/11/2018
12 | */
13 | public class ScouterConstantsTest {
14 |
15 | @Test
16 | public void toScouterObjName() {
17 | String name = "test-name";
18 | String expected = "ZIPKIN/test-name";
19 |
20 | assertEquals(expected, ScouterConstants.toScouterObjName(name));
21 | }
22 |
23 | @Test
24 | public void toScouterObjType() {
25 | ScouterConfig config = new ScouterConfig(false, "localhost", 6100, 60000,
26 | new HashMap<>(), "s1:xxs1,s2:xxs2");
27 |
28 | assertEquals("z$nomap", ScouterConstants.toScouterObjType("nomap", config));
29 | assertEquals("z$xxs1", ScouterConstants.toScouterObjType("s1", config));
30 | assertEquals("z$xxs2", ScouterConstants.toScouterObjType("s2", config));
31 | }
32 | }
--------------------------------------------------------------------------------
/storage-scouter-udp/src/test/java/zipkin2/storage/scouter/udp/net/DataProxyTest.java:
--------------------------------------------------------------------------------
1 | package zipkin2.storage.scouter.udp.net;
2 |
3 | import org.junit.Test;
4 | import scouter.lang.pack.SpanPack;
5 | import scouter.lang.value.MapValue;
6 |
7 | import static org.hamcrest.CoreMatchers.is;
8 | import static org.junit.Assert.*;
9 |
10 | /**
11 | * @author Gun Lee (gunlee01@gmail.com) on 11/11/2018
12 | */
13 | public class DataProxyTest {
14 | static SpanPack pack = new SpanPack();
15 | static {
16 | pack.tags = new MapValue();
17 | pack.tags.put("tag1", "tv1");
18 | pack.tags.put("tag2", "tv2");
19 | pack.tags.put("tag3", "tv3");
20 | }
21 |
22 | @Test
23 | public void map1stMatchingTagNames_no_matching() {
24 | assertNull(DataProxy.map1stMatchingTagNames(pack, "tagX"));
25 | assertNull(DataProxy.map1stMatchingTagNames(pack, "tagY"));
26 | assertNull(DataProxy.map1stMatchingTagNames(pack, "tagX,tagY"));
27 | }
28 |
29 | @Test
30 | public void map1stMatchingTagNames_matching() {
31 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tag1"), is(pack.tags.getText("tag1")));
32 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tag2"), is(pack.tags.getText("tag2")));
33 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tag1,tag2"), is(pack.tags.getText("tag1")));
34 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tag2,tag1"), is(pack.tags.getText("tag2")));
35 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tagX,tag1"), is(pack.tags.getText("tag1")));
36 | assertThat(DataProxy.map1stMatchingTagNames(pack, "tagX,tag2,tag3"), is(pack.tags.getText("tag2")));
37 | }
38 |
39 | @Test
40 | public void mapTagNames_no_matching() {
41 | assertThat(DataProxy.mapTagNames(pack, "tagX"), is(""));
42 | assertThat(DataProxy.mapTagNames(pack, "tagY"), is(""));
43 | assertThat(DataProxy.mapTagNames(pack, "tagX,tagY"), is(""));
44 | }
45 |
46 | @Test
47 | public void mapTagNames_matching() {
48 | assertThat(DataProxy.mapTagNames(pack, "tag1"), is("tv1"));
49 | assertThat(DataProxy.mapTagNames(pack, "tag2"), is("tv2"));
50 | assertThat(DataProxy.mapTagNames(pack, "tag1,tag2"), is("tv1,tv2"));
51 | assertThat(DataProxy.mapTagNames(pack, "tagX,tag1,tag2"), is("tv1,tv2"));
52 | assertThat(DataProxy.mapTagNames(pack, "tagX,tag1,tagX,tag2"), is("tv1,tv2"));
53 | assertThat(DataProxy.mapTagNames(pack, "tagX,tag1,tagX,tag2,tag3,tagX"), is("tv1,tv2,tv3"));
54 | }
55 | }
--------------------------------------------------------------------------------