Skip to content

Commit 4fbc118

Browse files
authored
docs: revamp README to match Python & JS SDKs better (#65)
1 parent c40e9ac commit 4fbc118

File tree

2 files changed

+107
-48
lines changed

2 files changed

+107
-48
lines changed

README.md

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@
99
<a href="https://logfire.pydantic.dev/docs/join-slack/"><img src="https://img.shields.io/badge/Slack-Join%20Slack-4A154B?logo=slack" alt="Join Slack" /></a>
1010
</p>
1111

12-
> ***Initial release - feedback wanted!***
13-
>
14-
> This is an initial release of the Logfire Rust SDK. We've been using it internally to build Logfire for some time, and it is serving us well. As we're using it ourselves in production, we figured it's ready for everyone else also using Logfire.
15-
>
16-
> We are continually iterating to make this SDK better. We'd love your feedback on all aspects of the SDK and are keen to make the design as idiomatic and performant as possible. There are also many features currently supported by the Python SDK which are not yet supported by this SDK; please open issues to help us prioritize these to close this gap.
17-
>
18-
> In particular, the current coupling to `tracing` is an open design point. By building on top of tracing we get widest compatibility and a relatively simple SDK, however to make Logfire-specific adjustments we might prefer in future to move `tracing` to be an optional integration.
19-
2012
From the team behind Pydantic, **Logfire** is an observability platform built on the same belief as our
2113
open source library — that the most powerful tools can be easy to use.
2214

15+
What sets Logfire apart:
16+
17+
- **Simple and Powerful:** Logfire's dashboard is simple relative to the power it provides, ensuring your entire engineering team will actually use it.
18+
- **SQL:** Query your data using standard SQL — all the control and (for many) nothing new to learn. Using SQL also means you can query your data with existing BI tools and database querying libraries.
19+
- **OpenTelemetry:** Logfire is an opinionated wrapper around OpenTelemetry, allowing you to leverage existing tooling, infrastructure, and instrumentation for many common Python packages, and enabling support for virtually any language. We offer full support for all OpenTelemetry signals (traces, metrics and logs).
20+
2321
This repository contains the Rust SDK for instrumenting with Logfire.
2422

2523
See also:
@@ -33,35 +31,74 @@ The Logfire server application for recording and displaying data is closed sourc
3331

3432
First [set up a Logfire project](https://logfire.pydantic.dev/docs/#logfire) and [create a write token](https://logfire.pydantic.dev/docs/how-to-guides/create-write-tokens/). You'll need to set this token as an environment variable (`LOGFIRE_TOKEN`) to export to Logfire.
3533

36-
Here's a simple manual tracing (aka logging) example:
37-
38-
```rust
39-
40-
fn main() -> Result<(), Box<dyn std::error::Error>> {
41-
let shutdown_handler = logfire::configure()
42-
.install_panic_handler()
43-
.finish()?;
34+
With a logfire project set up, start by adding the `logfire` crate to your `Cargo.toml`:
4435

45-
logfire::info!("Hello, {name}!", name = "world");
36+
```toml
37+
[dependencies]
38+
logfire = "0.6"
39+
```
4640

47-
{
48-
let _span = logfire::span!(
49-
"Asking the user their {question}",
50-
question = "age",
51-
).entered();
41+
Then, you can use the SDK to instrument the code. Here's a simple example which counts the size of files in the current directory, creating spans for the full operation and each file read:
5242

53-
println!("When were you born [YYYY-mm-dd]?");
54-
let mut dob = String::new();
55-
std::io::stdin().read_line(&mut dob)?;
5643

57-
logfire::debug!("dob={dob}", dob = dob.trim().to_owned());
58-
}
44+
```rust
45+
use std::fs;
46+
use std::sync::LazyLock;
47+
48+
use opentelemetry::{KeyValue, metrics::Counter};
49+
50+
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
51+
52+
fn main() -> Result<()> {
53+
let shutdown_handler = logfire::configure().install_panic_handler().finish()?;
54+
55+
let mut total_size = 0u64;
56+
57+
let cwd = std::env::current_dir()?;
58+
59+
logfire::span!("counting size of {cwd}", cwd = cwd.display().to_string()).in_scope(|| {
60+
let entries = fs::read_dir(&cwd)?;
61+
for entry in entries {
62+
let entry = entry?;
63+
let path = entry.path();
64+
65+
let _span = logfire::span!(
66+
"reading {path}",
67+
path = path
68+
.strip_prefix(&cwd)
69+
.unwrap_or(&path)
70+
.display()
71+
.to_string()
72+
)
73+
.entered();
74+
75+
let metadata = entry.metadata()?;
76+
if metadata.is_file() {
77+
total_size += metadata.len();
78+
}
79+
}
80+
Result::Ok(())
81+
})?;
82+
83+
logfire::info!(
84+
"total size of {cwd} is {size} bytes",
85+
cwd = cwd.display().to_string(),
86+
size = total_size as i64
87+
);
5988

6089
shutdown_handler.shutdown()?;
6190
Ok(())
6291
}
6392
```
6493

94+
(Read the [Logfire concepts documentation](https://logfire.pydantic.dev/docs/concepts/) for additional detail on spans, events, and further Logfire concepts.)
95+
96+
See additional examples in the [examples directory](https://github.com/pydantic/logfire-rust/tree/main/examples):
97+
98+
- [basic](https://github.com/pydantic/logfire-rust/tree/main/examples/basic.rs)
99+
- [axum webserver](https://github.com/pydantic/logfire-rust/tree/main/examples/axum.rs)
100+
- [actix webserver](https://github.com/pydantic/logfire-rust/tree/main/examples/actix-web.rs)
101+
65102
### Integration
66103

67104
Logfire's Rust SDK is currently built directly upon [`tracing`](https://docs.rs/tracing/latest/tracing/) and [`opentelemetry`](https://github.com/open-telemetry/opentelemetry-rust/).

examples/basic.rs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,57 @@
11
//! A basic example of using Logfire to instrument Rust code.
22
3+
use std::fs;
34
use std::sync::LazyLock;
45

56
use opentelemetry::{KeyValue, metrics::Counter};
67

7-
static BASIC_COUNTER: LazyLock<Counter<u64>> = LazyLock::new(|| {
8-
logfire::u64_counter("basic_counter")
8+
static FILES_COUNTER: LazyLock<Counter<u64>> = LazyLock::new(|| {
9+
logfire::u64_counter("FILES_COUNTER")
910
.with_description("Just an example")
1011
.with_unit("s")
1112
.build()
1213
});
1314

14-
fn main() -> Result<(), Box<dyn std::error::Error>> {
15-
let shutdown_handler = logfire::configure()
16-
.install_panic_handler()
17-
.with_console(None)
18-
.finish()?;
19-
20-
tracing::info!("Hello, world!");
21-
22-
{
23-
let _span = logfire::span!("Asking the user their {question}", question = "age").entered();
24-
25-
println!("When were you born [YYYY-mm-dd]?");
26-
let mut dob = String::new();
27-
std::io::stdin().read_line(&mut dob)?;
28-
29-
logfire::debug!("dob={dob}", dob = dob.trim().to_owned());
30-
}
31-
32-
BASIC_COUNTER.add(1, &[KeyValue::new("process", "abc123")]);
15+
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
16+
17+
fn main() -> Result<()> {
18+
let shutdown_handler = logfire::configure().install_panic_handler().finish()?;
19+
20+
let mut total_size = 0u64;
21+
22+
let cwd = std::env::current_dir()?;
23+
24+
logfire::span!("counting size of {cwd}", cwd = cwd.display().to_string()).in_scope(|| {
25+
let entries = fs::read_dir(&cwd)?;
26+
for entry in entries {
27+
let entry = entry?;
28+
let path = entry.path();
29+
30+
let _span = logfire::span!(
31+
"reading {path}",
32+
path = path
33+
.strip_prefix(&cwd)
34+
.unwrap_or(&path)
35+
.display()
36+
.to_string()
37+
)
38+
.entered();
39+
40+
FILES_COUNTER.add(1, &[KeyValue::new("process", "abc123")]);
41+
42+
let metadata = entry.metadata()?;
43+
if metadata.is_file() {
44+
total_size += metadata.len();
45+
}
46+
}
47+
Result::Ok(())
48+
})?;
49+
50+
logfire::info!(
51+
"total size of {cwd} is {size} bytes",
52+
cwd = cwd.display().to_string(),
53+
size = total_size as i64
54+
);
3355

3456
shutdown_handler.shutdown()?;
3557
Ok(())

0 commit comments

Comments
 (0)