Skip to content

Commit b8a4a18

Browse files
authored
Add logging. (#41)
1 parent c6ec104 commit b8a4a18

25 files changed

+1046
-430
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ tokio-stream = { version = "0.1.8", features = ["net"] }
6262
name = "trace_context"
6363
required-features = ["mock"]
6464

65+
[[test]]
66+
name = "logging"
67+
required-features = ["mock"]
68+
6569
[[example]]
6670
name = "simple_trace_report"
6771
path = "examples/simple_trace_report.rs"

README.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ and core concepts to keep best compatibility and performance.
1616

1717
All concepts are from the official SkyWalking definitions.
1818

19-
## Span
19+
## Tracing
20+
21+
### Span
2022

2123
Span is an important and common concept in distributed tracing system. Learn Span from Google Dapper Paper. For better
2224
performance, we extend the span into 3 kinds.
@@ -34,19 +36,29 @@ Tag and Log are similar attributes of the span.
3436
- Log is heavier than tag, with one timestamp and multiple key:value pairs. Log represents an event, typically an error
3537
happens.
3638

37-
## TracingContext
39+
### TracingContext
3840

3941
TracingContext is the context of the tracing process. Span should only be created through context, and be archived into
4042
the context after the span finished.
4143

44+
## Logging
45+
46+
### LogRecord
47+
48+
LogRecord is the simple builder for the LogData, which is the Log format of Skywalking.
49+
4250
# Example
4351

4452
```rust, no_run
45-
use skywalking::{reporter::grpc::GrpcReporter, trace::tracer::Tracer};
53+
use skywalking::{
54+
logging::{logger::Logger, record::{LogRecord, RecordType}},
55+
reporter::grpc::GrpcReporter,
56+
trace::tracer::Tracer,
57+
};
4658
use std::error::Error;
4759
use tokio::signal;
4860
49-
async fn handle_request(tracer: Tracer) {
61+
async fn handle_request(tracer: Tracer, logger: Logger) {
5062
let mut ctx = tracer.create_trace_context();
5163
5264
{
@@ -59,10 +71,20 @@ async fn handle_request(tracer: Tracer) {
5971
6072
{
6173
// Generates an Exit Span when executing an RPC.
62-
let _span2 = ctx.create_exit_span("op2", "remote_peer");
74+
let span2 = ctx.create_exit_span("op2", "remote_peer");
6375
6476
// Something...
6577
78+
// Do logging.
79+
logger.log(
80+
LogRecord::new()
81+
.add_tag("level", "INFO")
82+
.with_tracing_context(&ctx)
83+
.with_span(&span2)
84+
.record_type(RecordType::Text)
85+
.content("Something...")
86+
);
87+
6688
// Auto close span2 when dropped.
6789
}
6890
@@ -74,17 +96,24 @@ async fn handle_request(tracer: Tracer) {
7496
7597
#[tokio::main]
7698
async fn main() -> Result<(), Box<dyn Error>> {
99+
// Connect to skywalking oap server.
77100
let reporter = GrpcReporter::connect("http://0.0.0.0:11800").await?;
78-
let tracer = Tracer::new("service", "instance", reporter);
79101
80-
tokio::spawn(handle_request(tracer.clone()));
81-
82-
// Start to report.
83-
tracer
84-
.reporting(async move {
85-
let _ = signal::ctrl_c().await.unwrap();
102+
// Spawn the reporting in background, with listening the graceful shutdown signal.
103+
let handle = reporter
104+
.reporting()
105+
.await
106+
.with_graceful_shutdown(async move {
107+
signal::ctrl_c().await.expect("failed to listen for event");
86108
})
87-
.await?;
109+
.spawn();
110+
111+
let tracer = Tracer::new("service", "instance", reporter.clone());
112+
let logger = Logger::new("service", "instance", reporter);
113+
114+
handle_request(tracer, logger).await;
115+
116+
handle.await?;
88117
89118
Ok(())
90119
}

docker-compose.e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
version: "3.9"
1919
services:
2020
collector:
21-
image: ghcr.io/apache/skywalking-agent-test-tool/mock-collector:5acb890f225ca37ee60675ce3e330545e23e3cbc
21+
image: ghcr.io/apache/skywalking-agent-test-tool/mock-collector:f4f5ef22b1df623464772816bb6b42ba611444ff
2222
ports:
2323
- "19876:19876"
2424
- "12800:12800"

e2e/data/expected_context.yaml

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# under the License.
1717
#
1818
segmentItems:
19-
- segmentSize: gt 1
19+
- segmentSize: ge 2
2020
segments:
2121
- segmentId: not null
2222
spans:
@@ -76,7 +76,7 @@ segmentItems:
7676
spanType: Entry
7777
startTime: gt 0
7878
serviceName: producer
79-
- segmentSize: 1
79+
- segmentSize: ge 1
8080
segments:
8181
- segmentId: not null
8282
spans:
@@ -101,3 +101,48 @@ segmentItems:
101101
spanType: Entry
102102
startTime: gt 0
103103
serviceName: consumer
104+
105+
logItems:
106+
- logSize: ge 2
107+
logs:
108+
- body:
109+
content:
110+
json: '{"message": "handle ping"}'
111+
type: ''
112+
endpoint: /ping
113+
layer: ''
114+
tags:
115+
data:
116+
- key: level
117+
value: DEBUG
118+
timestamp: gt 0
119+
- body:
120+
content:
121+
text: do http request
122+
type: ''
123+
endpoint: /ping
124+
layer: ''
125+
tags:
126+
data:
127+
- key: level
128+
value: INFO
129+
timestamp: gt 0
130+
traceContext:
131+
spanId: 1
132+
traceId: not null
133+
traceSegmentId: not null
134+
serviceName: producer
135+
- logSize: ge 1
136+
logs:
137+
- body:
138+
content:
139+
json: '{"message": "handle pong"}'
140+
type: ''
141+
endpoint: /pong
142+
layer: ''
143+
tags:
144+
data:
145+
- key: level
146+
value: DEBUG
147+
timestamp: gt 0
148+
serviceName: consumer

e2e/rust-toolchain.toml

Lines changed: 0 additions & 20 deletions
This file was deleted.

e2e/src/main.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ use hyper::{
2121
Body, Client, Method, Request, Response, Server, StatusCode,
2222
};
2323
use skywalking::{
24+
logging::{
25+
logger::{self, Logger},
26+
record::{LogRecord, RecordType},
27+
},
2428
reporter::grpc::GrpcReporter,
2529
trace::{
2630
propagation::{
@@ -30,7 +34,7 @@ use skywalking::{
3034
tracer::{self, Tracer},
3135
},
3236
};
33-
use std::{convert::Infallible, error::Error, future, net::SocketAddr};
37+
use std::{convert::Infallible, error::Error, net::SocketAddr};
3438
use structopt::StructOpt;
3539

3640
static NOT_FOUND_MSG: &str = "not found";
@@ -40,10 +44,18 @@ async fn handle_ping(
4044
_req: Request<Body>,
4145
client: Client<HttpConnector>,
4246
) -> Result<Response<Body>, Infallible> {
47+
logger::log(
48+
LogRecord::new()
49+
.add_tag("level", "DEBUG")
50+
.endpoint("/ping")
51+
.record_type(RecordType::Json)
52+
.content(r#"{"message": "handle ping"}"#),
53+
);
54+
4355
let mut context = tracer::create_trace_context();
4456
let _span = context.create_entry_span("/ping");
4557
{
46-
let _span2 = context.create_exit_span("/pong", "consumer:8082");
58+
let span2 = context.create_exit_span("/pong", "consumer:8082");
4759
let header = encode_propagation(&context, "/pong", "consumer:8082");
4860
let req = Request::builder()
4961
.method(Method::GET)
@@ -52,6 +64,15 @@ async fn handle_ping(
5264
.body(Body::from(""))
5365
.unwrap();
5466

67+
logger::log(
68+
LogRecord::new()
69+
.add_tag("level", "INFO")
70+
.endpoint("/ping")
71+
.with_tracing_context(&context)
72+
.with_span(&span2)
73+
.record_type(RecordType::Text)
74+
.content("do http request"),
75+
);
5576
client.request(req).await.unwrap();
5677
}
5778
{
@@ -106,6 +127,14 @@ async fn run_producer_service(host: [u8; 4]) {
106127
}
107128

108129
async fn handle_pong(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
130+
logger::log(
131+
LogRecord::new()
132+
.add_tag("level", "DEBUG")
133+
.endpoint("/pong")
134+
.record_type(RecordType::Json)
135+
.content(r#"{"message": "handle pong"}"#),
136+
);
137+
109138
let ctx = decode_propagation(
110139
_req.headers()[SKYWALKING_HTTP_CONTEXT_HEADER_KEY]
111140
.to_str()
@@ -154,20 +183,19 @@ struct Opt {
154183
async fn main() -> Result<(), Box<dyn Error>> {
155184
let opt = Opt::from_args();
156185
let reporter = GrpcReporter::connect("http://collector:19876").await?;
186+
let handle = reporter.reporting().await.spawn();
157187

158-
let handle = if opt.mode == "consumer" {
159-
tracer::set_global_tracer(Tracer::new("consumer", "node_0", reporter));
160-
let handle = tracer::reporting(future::pending());
188+
if opt.mode == "consumer" {
189+
tracer::set_global_tracer(Tracer::new("consumer", "node_0", reporter.clone()));
190+
logger::set_global_logger(Logger::new("consumer", "node_0", reporter));
161191
run_consumer_service([0, 0, 0, 0]).await;
162-
handle
163192
} else if opt.mode == "producer" {
164-
tracer::set_global_tracer(Tracer::new("producer", "node_0", reporter));
165-
let handle = tracer::reporting(future::pending());
193+
tracer::set_global_tracer(Tracer::new("producer", "node_0", reporter.clone()));
194+
logger::set_global_logger(Logger::new("producer", "node_0", reporter));
166195
run_producer_service([0, 0, 0, 0]).await;
167-
handle
168196
} else {
169197
unreachable!()
170-
};
198+
}
171199

172200
handle.await?;
173201

examples/simple_log_report.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. 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,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
//
18+
19+
use skywalking::{
20+
logging::{logger::Logger, record::LogRecord},
21+
reporter::grpc::GrpcReporter,
22+
};
23+
use std::{error::Error, future};
24+
25+
#[tokio::main]
26+
async fn main() -> Result<(), Box<dyn Error>> {
27+
// Connect to skywalking oap server.
28+
let reporter = GrpcReporter::connect("http://0.0.0.0:11800").await?;
29+
30+
// Do logging.
31+
let logger = Logger::new("service", "instance", reporter.clone());
32+
logger.log(LogRecord::new().content("something to log"));
33+
34+
// Start reporting and quit immediately when have completed the existing
35+
// collection.
36+
reporter
37+
.reporting()
38+
.await
39+
.with_graceful_shutdown(future::ready(()))
40+
.start()
41+
.await?;
42+
43+
Ok(())
44+
}

examples/simple_trace_report.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,25 @@ async fn handle_request(tracer: Tracer) {
4848

4949
#[tokio::main]
5050
async fn main() -> Result<(), Box<dyn Error>> {
51+
// Connect to skywalking oap server.
5152
let reporter = GrpcReporter::connect("http://0.0.0.0:11800").await?;
52-
let tracer = Tracer::new("service", "instance", reporter);
53-
54-
tokio::spawn(handle_request(tracer.clone()));
5553

56-
// Start to report.
57-
tracer
58-
.reporting(async move {
59-
let _ = signal::ctrl_c().await.unwrap();
54+
// Spawn the reporting in background, with listening the graceful shutdown
55+
// signal.
56+
let handle = reporter
57+
.reporting()
58+
.await
59+
.with_graceful_shutdown(async move {
60+
signal::ctrl_c().await.expect("failed to listen for event");
6061
})
61-
.await?;
62+
.spawn();
63+
64+
// Do tracing.
65+
let tracer = Tracer::new("service", "instance", reporter);
66+
handle_request(tracer).await;
67+
68+
// Wait the reporting to quit.
69+
handle.await?;
6270

6371
Ok(())
6472
}

src/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
//
1616

1717
pub mod random_generator;
18+
pub(crate) mod system_time;
File renamed without changes.

0 commit comments

Comments
 (0)