Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of the logging SDK spec #788

Merged
merged 52 commits into from
May 17, 2023

Conversation

vibhavp
Copy link
Contributor

@vibhavp vibhavp commented Apr 29, 2022

This PR is a first stab at implementing the logging SDK specification. Owing to the similar nature of traces and logging data, it's mostly a s/span/log/g on the trace SDK, but without corresponding additions to the api package, as the specification's intent is for the SDK to be used by logging libraries, not developers.

There is a bit of duplication, especially with respect to how the batching is implemented, and I'm curious in seeing whether that could be resolved by unifying TraceRuntime and LogRuntime into a signal-agnostic trait.

@vibhavp vibhavp requested a review from a team April 29, 2022 07:23
Copy link
Member

@jtescher jtescher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great step thanks for starting this, the duplication between runtimes is indeed unfortunate, we could look at unifying those in subsequent PRs. Also note the changes discussed in #781.

opentelemetry-api/Cargo.toml Outdated Show resolved Hide resolved
opentelemetry-api/src/lib.rs Outdated Show resolved Hide resolved
opentelemetry-sdk/src/log/record.rs Outdated Show resolved Hide resolved
/// span.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct TraceContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe LogTraceContext to disambiguate from other trace context concepts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it refers to W3C trace context standard. Maybe we can merge it with the definition in trace mod?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just confusing as the concept is used multiple places, like the TraceContextPropagator doesn't use this and the TraceContextExt doesn't involve it either (maybe the ext should be renamed as well to disambiguate?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe easier to divide the trace context field into trace id, span id, and trace flag and use the basic types. Or alternatively, those fields should only be present when trace is enabled. so that we can just refer the types from trace mod

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is SpanContext, which stores the span ID, trace ID, and trace flags. However, it also stores an additional TraceState field, which is not in a Log Record. That's why I had to create this field.


/// Value types for representing arbitrary values in a log record.
#[derive(Debug, Clone)]
pub enum Any {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec calls this typeAny but this may be confusing as people may read it as std::any::Any, possibly LogBody, AnyBody, or something slightly more specific? also would be nice to have these be as consistent with the Value type as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about LogAnyor AnyValue? I initially wanted to reuse Value, but both the spec and the Rust implementation mandate that an Array be homogenous in its member types.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about LogAnyor AnyValue? I initially wanted to reuse Value, but both the spec and the Rust implementation mandate that an Array be homogenous in its member types.

Those seem reasonable 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed this to AnyValue.

opentelemetry-proto/tests/grpc_build.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@TommyCpp TommyCpp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this I think it's a good start!

opentelemetry-api/src/global/error_handler.rs Show resolved Hide resolved
opentelemetry-proto/src/transform/logs.rs Outdated Show resolved Hide resolved
opentelemetry-proto/src/transform/logs.rs Outdated Show resolved Hide resolved
.0,
dropped_attributes_count: 0,
}),
schema_url: "".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe leave a TODO here to implement the schema url in the furture

opentelemetry-proto/src/transform/logs.rs Outdated Show resolved Hide resolved
opentelemetry-sdk/src/log/log_emitter.rs Outdated Show resolved Hide resolved
opentelemetry-sdk/src/log/log_emitter.rs Outdated Show resolved Hide resolved
opentelemetry-sdk/src/log/log_processor.rs Outdated Show resolved Hide resolved
opentelemetry-sdk/src/log/log_processor.rs Outdated Show resolved Hide resolved
/// span.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct TraceContext {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it refers to W3C trace context standard. Maybe we can merge it with the definition in trace mod?

@TmLev
Copy link

TmLev commented Feb 22, 2023

Hey there!

What's the status of this PR? Maybe some help needed?

@hdost
Copy link
Contributor

hdost commented Apr 11, 2023

👋🏼 @vibhavp thank you again for making the PR, do you mind if we rebase this on main?

@codecov
Copy link

codecov bot commented Apr 30, 2023

Codecov Report

Patch coverage: 0.5% and project coverage change: -4.3 ⚠️

Comparison is base (f42c11d) 55.1% compared to head (59469cb) 50.9%.

Additional details and impacted files
@@           Coverage Diff           @@
##            main    #788     +/-   ##
=======================================
- Coverage   55.1%   50.9%   -4.3%     
=======================================
  Files        149     165     +16     
  Lines      18143   19686   +1543     
=======================================
+ Hits       10006   10025     +19     
- Misses      8137    9661   +1524     
Impacted Files Coverage Δ
opentelemetry-api/src/common.rs 77.4% <0.0%> (-2.2%) ⬇️
opentelemetry-api/src/global/error_handler.rs 27.2% <0.0%> (-1.3%) ⬇️
opentelemetry-api/src/global/logs.rs 0.0% <0.0%> (ø)
opentelemetry-api/src/lib.rs 100.0% <ø> (ø)
opentelemetry-api/src/logs/logger.rs 0.0% <0.0%> (ø)
opentelemetry-api/src/logs/mod.rs 0.0% <0.0%> (ø)
opentelemetry-api/src/logs/noop.rs 0.0% <0.0%> (ø)
opentelemetry-api/src/logs/record.rs 0.0% <0.0%> (ø)
opentelemetry-otlp/src/lib.rs 29.7% <ø> (ø)
opentelemetry-otlp/src/logs.rs 0.0% <0.0%> (ø)
... and 14 more

... and 23 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.


fn versioned_logger(
&self,
name: Cow<'static, str>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be: name: impl Into<Cow<'static, str>>,
this will allow us to directly pass string literal as name argument.

attributes: Option<Vec<KeyValue>>,
) -> Self::Logger;

fn logger(&self, name: Cow<'static, str>) -> Self::Logger {
Copy link
Member

@lalitb lalitb May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name argument can be: name: impl Into<Cow<'static, str>>
this will allow us to directly pass string literal as argument.

@lalitb
Copy link
Member

lalitb commented May 10, 2023

Thanks @TommyCpp for fixing lint. As discussed in the community meeting, do you think we can merge this PR, as that will allows others to incrementally contribute the improvements over this. I did some trivial testing using ostream-exporter, and the logs are printed successfully to standard output.

Copy link
Member

@cijothomas cijothomas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@cijothomas
Copy link
Member

Thanks @TommyCpp for fixing lint. As discussed in the community meeting, do you think we can merge this PR, as that will allows others to incrementally contribute the improvements over this. I did some trivial testing using ostream-exporter, and the logs are printed successfully to standard output.

@jtescher Could you also take another look? There is a request-changes from your earlier review.

Copy link
Member

@jtescher jtescher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still needs some cleanup and I'd like to see the Any type renamed as it conflicts with the type in the standard library, but we can do it follow up changes as well.

use std::{borrow::Cow, fmt::Debug};

/// `LogExporter` defines the interface that log exporters should implement.
#[async_trait]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think traits that every 3rd-party exporter is expected to implement should be forcing non-standard things like the async-trait crate. It's hacky and unnecessary, and will probably turn into an issue in the future when/if built-in support for async functions in traits shows up.

While the SpanExporter's BoxedFuture is unpleasant, it feels like a more future-proof design and one that is less burdensome on developers.

Copy link
Member

@lalitb lalitb May 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, exporter trait needn't be async, and let the processor decide how export would be invoked. We can keep this consistent with SpanExporter -

pub trait SpanExporter: Send + Debug {

fn drop(&mut self) {
match self.try_shutdown() {
None => handle_error(Error::Other(
"canont shutdown LoggerProvider when child Loggers are still active".into(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cannot

pub type LogResult<T> = Result<T, LogError>;

#[derive(Error, Debug)]
#[non_exhaustive]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More a comment for when we look to stabilize, but non-exhaustive is a double edged sword because while adding a new enum value is considered breaking without it because code will fail to compile. It might be worse to have people think they covered all errors and then find out at runtime.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, better to fail early at compile time. Probably we can remove non-exhaustive attribute before releasing stable version of logs.

}

/// OTLP exporter that sends log data
pub enum LogExporter {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For another review: the builder is non_exhausive but the Exporter isn't?

@cijothomas
Copy link
Member

@TommyCpp @hdost Could we merge this, given major feedbacks are already addressed, and we can iterate on this further.

@TommyCpp
Copy link
Contributor

Sounds good! Thank you for working on this @vibhavp and appriciate everyone that reviewed it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants