Skip to content

Commit

Permalink
Merge pull request #87 from frigus02/otel-0.24
Browse files Browse the repository at this point in the history
Update to OpenTelemetry 0.24
  • Loading branch information
frigus02 authored Jul 20, 2024
2 parents 4d14d02 + f416c3a commit 85aee7b
Show file tree
Hide file tree
Showing 21 changed files with 370 additions and 293 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ jobs:
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Run cargo build (trace only)
uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features trace
- name: Run cargo build (logs only)
uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features logs
- name: Run cargo build (metrics only)
uses: actions-rs/cargo@v1
with:
command: build
args: --no-default-features --features metrics
- name: Run cargo test
uses: actions-rs/cargo@v1
with:
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

- Upgrade `opentelemetry` and `opentelemetry_sdk` to `v0.24`.
- Upgrade `opentelemetry-http` to `v0.13`.
- Upgrade `opentelemetry-semantic-conventions` to `v0.16`.
- Upgrade `http` to `1` and `reqwest` to `0.12`.
- Add `trace` feature and enable `trace`, `logs` and `metrics` by default. This mimicks opentelemetry.

## [0.33.0] - 2024-06-09

- Add support for exporting logs, e.g. using one of the `opentelemetry-appender-*` crates.
Expand Down
37 changes: 18 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,33 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
default = ["trace", "metrics", "logs"]
trace = ["opentelemetry_sdk/trace"]
metrics = ["opentelemetry_sdk/metrics"]
logs = ["opentelemetry_sdk/logs"]
live-metrics = ["trace", "futures-util", "sysinfo"]
# Deprecated features: These don't enable anything in
# opentelemetry-application-insights. They only enable features in dependency
# crates.
reqwest-blocking-client = ["reqwest-client"]
reqwest-blocking-client-rustls = ["reqwest-client-rustls"]
reqwest-client = ["opentelemetry-http/reqwest", "reqwest/native-tls"]
reqwest-client-vendored-tls = ["opentelemetry-http/reqwest", "reqwest/native-tls-vendored"]
reqwest-client-rustls = ["opentelemetry-http/reqwest", "reqwest/rustls-tls"]
metrics = ["opentelemetry_sdk/metrics"]
logs = ["opentelemetry_sdk/logs"]
live-metrics = ["futures-util", "sysinfo"]

[dependencies]
async-trait = "0.1"
bytes = "1"
chrono = "0.4"
flate2 = "1"
http = "0.2"
http = "1"
once_cell = "1"
futures-util = { version = "0.3", default-features = false, optional = true }
opentelemetry = "0.23"
opentelemetry_sdk = "0.23"
opentelemetry-http = "0.12"
opentelemetry-semantic-conventions = "0.15"
reqwest = { version = "0.11", default-features = false, features = ["blocking"], optional = true }
opentelemetry = "0.24"
opentelemetry_sdk = "0.24"
opentelemetry-http = "0.13"
opentelemetry-semantic-conventions = "0.16"
reqwest = { version = "0.12", default-features = false, features = ["blocking"], optional = true }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_repr = "0.1"
Expand All @@ -56,15 +61,13 @@ async-std = { version = "1.12.0", features = ["attributes"] }
doc-comment = "0.3.3"
env_logger = "0.11.3"
insta = "1.39.0"
isahc = "1.7.2"
log = { version = "0.4", features = ["kv", "kv_sval"] }
opentelemetry_sdk = { version = "0.23", features = ["rt-async-std", "rt-tokio", "rt-tokio-current-thread", "logs_level_enabled"] }
opentelemetry-http = { version = "0.12", features = ["reqwest"] }
opentelemetry-appender-log = { version = "0.4", features = ["with-serde"] }
opentelemetry-application-insights = { path = ".", features = ["logs", "live-metrics"] }
opentelemetry_sdk = { version = "0.24", features = ["rt-async-std", "rt-tokio", "rt-tokio-current-thread", "logs_level_enabled"] }
opentelemetry-http = { version = "0.13", features = ["reqwest"] }
opentelemetry-appender-log = { version = "0.5", features = ["with-serde"] }
rand = "0.8.5"
regex = "1.10.5"
reqwest = { version = "0.11", features = ["blocking"] }
reqwest = { version = "0.12", features = ["blocking"] }
test-case = "3.3.1"
tokio = { version = "1.38.0", features = ["rt-multi-thread", "macros", "process", "time"] }
version-sync = { version = "0.9.5", default-features = false, features = ["html_root_url_updated", "contains_regex"] }
Expand All @@ -76,10 +79,6 @@ github = { repository = "frigus02/opentelemetry-application-insights", workflow
name = "attributes"
required-features = ["opentelemetry-http/reqwest"]

[[example]]
name = "http_client_isahc"
required-features = ["opentelemetry_sdk/rt-async-std", "opentelemetry-http/isahc"]

[[example]]
name = "http_client_reqwest"
required-features = ["opentelemetry_sdk/rt-tokio", "opentelemetry-http/reqwest"]
Expand Down
16 changes: 8 additions & 8 deletions examples/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,26 @@ fn main() {
let client_provider = opentelemetry_application_insights::new_pipeline_from_env()
.expect("env var APPLICATIONINSIGHTS_CONNECTION_STRING should exist")
.with_client(reqwest::blocking::Client::new())
.with_trace_config(
opentelemetry_sdk::trace::config().with_resource(Resource::new(vec![
.with_trace_config(opentelemetry_sdk::trace::Config::default().with_resource(
Resource::new(vec![
KeyValue::new(semcov::resource::SERVICE_NAMESPACE, "example-attributes"),
KeyValue::new(semcov::resource::SERVICE_NAME, "client"),
KeyValue::new(semcov::resource::DEVICE_ID, "123"),
KeyValue::new(semcov::resource::DEVICE_MODEL_NAME, "Foo Phone"),
])),
)
]),
))
.build_simple();
let client_tracer = client_provider.tracer("example-attributes");

let server_provider = opentelemetry_application_insights::new_pipeline_from_env()
.expect("env var APPLICATIONINSIGHTS_CONNECTION_STRING should exist")
.with_client(reqwest::blocking::Client::new())
.with_trace_config(
opentelemetry_sdk::trace::config().with_resource(Resource::new(vec![
.with_trace_config(opentelemetry_sdk::trace::Config::default().with_resource(
Resource::new(vec![
KeyValue::new(semcov::resource::SERVICE_NAMESPACE, "example-attributes"),
KeyValue::new(semcov::resource::SERVICE_NAME, "server"),
])),
)
]),
))
.build_simple();
let server_tracer = server_provider.tracer("example-attributes");

Expand Down
15 changes: 0 additions & 15 deletions examples/http_client_isahc.rs

This file was deleted.

10 changes: 4 additions & 6 deletions examples/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
.expect("connection string is valid");
let logger_provider = opentelemetry_sdk::logs::LoggerProvider::builder()
.with_batch_exporter(exporter, opentelemetry_sdk::runtime::Tokio)
.with_config(
opentelemetry_sdk::logs::config().with_resource(Resource::new(vec![
KeyValue::new(semcov::resource::SERVICE_NAMESPACE, "test"),
KeyValue::new(semcov::resource::SERVICE_NAME, "client"),
])),
)
.with_resource(Resource::new(vec![
KeyValue::new(semcov::resource::SERVICE_NAMESPACE, "test"),
KeyValue::new(semcov::resource::SERVICE_NAME, "client"),
]))
.build();
let otel_log_appender =
opentelemetry_appender_log::OpenTelemetryLogBridge::new(&logger_provider);
Expand Down
6 changes: 3 additions & 3 deletions examples/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use opentelemetry::{global, metrics::Unit, KeyValue};
use opentelemetry::{global, KeyValue};
use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider};
use rand::{thread_rng, Rng};
use std::{error::Error, time::Duration};
Expand All @@ -24,7 +24,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Observable
let _cpu_utilization_gauge = meter
.f64_observable_gauge("system.cpu.utilization")
.with_unit(Unit::new("1"))
.with_unit("1")
.with_callback(|instrument| {
let mut rng = thread_rng();
instrument.observe(
Expand All @@ -37,7 +37,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
// Recorder
let server_duration = meter
.u64_histogram("http.server.duration")
.with_unit(Unit::new("milliseconds"))
.with_unit("milliseconds")
.init();
let mut rng = thread_rng();
for _ in 1..10 {
Expand Down
37 changes: 26 additions & 11 deletions src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use crate::models::{serialize_ms_links, Properties, SeverityLevel, MS_LINKS_KEY};
#[cfg(any(feature = "trace", feature = "logs"))]
use crate::models::Properties;
#[cfg(feature = "trace")]
use crate::models::{serialize_ms_links, SeverityLevel, MS_LINKS_KEY};
use chrono::{DateTime, SecondsFormat, Utc};
#[cfg(feature = "trace")]
use opentelemetry::trace::{Link, Status};
#[cfg(any(feature = "trace", feature = "logs"))]
use opentelemetry::KeyValue;
use opentelemetry::Value;
#[cfg(feature = "logs")]
use opentelemetry::{logs::AnyValue, Key};
use opentelemetry::{
trace::{Link, Status},
KeyValue, Value,
};
#[cfg(any(feature = "trace", feature = "logs"))]
use opentelemetry_sdk::Resource;
use std::{
borrow::Cow,
collections::HashMap,
time::{Duration, SystemTime},
};
#[cfg(any(feature = "trace", feature = "logs"))]
use std::collections::HashMap;
#[cfg(feature = "trace")]
use std::time::Duration;
use std::{borrow::Cow, time::SystemTime};

#[cfg(feature = "trace")]
pub(crate) fn duration_to_string(duration: Duration) -> String {
let micros = duration.as_micros();
let s = micros / 1_000_000 % 60;
Expand All @@ -30,14 +36,16 @@ pub(crate) fn time_to_string(time: SystemTime) -> String {
DateTime::<Utc>::from(time).to_rfc3339_opts(SecondsFormat::Millis, true)
}

#[cfg(any(feature = "trace", feature = "logs"))]
pub(crate) fn attrs_to_properties<'a, T>(
attributes: &'a [T],
resource: Option<&Resource>,
links: &[Link],
#[cfg(feature = "trace")] links: &[Link],
) -> Option<Properties>
where
&'a T: Into<AttrKeyValue<'a>>,
{
#[allow(unused_mut)]
let mut properties: Properties = attributes
.iter()
.map(|kv| kv.into())
Expand All @@ -51,13 +59,15 @@ where
.map(|(k, v)| (k.into(), v.as_str().into()))
.collect();

#[cfg(feature = "trace")]
if !links.is_empty() {
properties.insert(MS_LINKS_KEY.into(), serialize_ms_links(links).into());
}

Some(properties).filter(|x| !x.is_empty())
}

#[cfg(any(feature = "trace", feature = "logs"))]
pub(crate) fn attrs_to_map<'a, T>(attributes: &'a [T]) -> HashMap<&str, &dyn AttrValue>
where
&'a T: Into<AttrKeyValue<'a>>,
Expand All @@ -69,6 +79,7 @@ where
.collect()
}

#[cfg(any(feature = "trace", feature = "logs"))]
pub(crate) fn attrs_map_to_properties(
attributes: HashMap<&str, &dyn AttrValue>,
) -> Option<Properties> {
Expand All @@ -81,6 +92,7 @@ pub(crate) fn attrs_map_to_properties(
Some(properties).filter(|x| !x.is_empty())
}

#[cfg(feature = "trace")]
pub(crate) fn status_to_result_code(status: &Status) -> i32 {
// Since responseCode is a required field for RequestData, we map the span status to come kind
// of result code representation. Numbers 1-3 were chosen because in [email protected]
Expand All @@ -92,6 +104,7 @@ pub(crate) fn status_to_result_code(status: &Status) -> i32 {
}
}

#[cfg(feature = "trace")]
pub(crate) fn value_to_severity_level(value: &dyn AttrValue) -> Option<SeverityLevel> {
match value.as_str().as_ref() {
// Convert from `tracing` Level.
Expand All @@ -105,8 +118,10 @@ pub(crate) fn value_to_severity_level(value: &dyn AttrValue) -> Option<SeverityL
}
}

#[cfg(any(feature = "trace", feature = "logs"))]
pub(crate) struct AttrKeyValue<'a>(&'a str, &'a dyn AttrValue);

#[cfg(any(feature = "trace", feature = "logs"))]
impl<'a> From<&'a KeyValue> for AttrKeyValue<'a> {
fn from(kv: &'a KeyValue) -> Self {
AttrKeyValue(kv.key.as_str(), &kv.value as &dyn AttrValue)
Expand Down
Loading

0 comments on commit 85aee7b

Please sign in to comment.