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

O11Y-1665: Stub out remaining interface methods in opentelemetry-dart #43

Merged
merged 7 commits into from
Apr 15, 2022
3 changes: 2 additions & 1 deletion lib/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ export 'src/api/trace/id_generator.dart' show IdGenerator;
export 'src/api/trace/nonrecording_span.dart' show NonRecordingSpan;
export 'src/api/trace/sampler.dart' show Sampler;
export 'src/api/trace/sampling_result.dart' show Decision, SamplingResult;
export 'src/api/trace/span.dart' show Span;
export 'src/api/trace/span.dart' show Span, SpanKind;
export 'src/api/trace/span_context.dart' show SpanContext;
export 'src/api/trace/span_id.dart' show SpanId;
export 'src/api/trace/span_link.dart' show SpanLink;
export 'src/api/trace/span_status.dart' show SpanStatus, StatusCode;
export 'src/api/trace/trace_flags.dart' show TraceFlags;
export 'src/api/trace/trace_id.dart' show TraceId;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/api/exporters/span_exporter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ import '../../../api.dart' as api;
abstract class SpanExporter {
void export(List<api.Span> spans);

void forceFlush();

void shutdown();
}
9 changes: 9 additions & 0 deletions lib/src/api/trace/nonrecording_span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class NonRecordingSpan implements api.Span {
@override
String get name => 'NON_RECORDING';

@override
set name(String _name) {}

@override
bool get isRecording => false;

Expand All @@ -56,4 +59,10 @@ class NonRecordingSpan implements api.Span {

@override
void recordException(dynamic exception, {StackTrace stackTrace}) {}

@override
void addEvent(String name, Int64 timestamp, {api.Attributes attributes}) {}

@override
api.SpanKind get kind => api.SpanKind.internal;
}
8 changes: 7 additions & 1 deletion lib/src/api/trace/noop_tracer.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:fixnum/fixnum.dart';

import '../../../api.dart' as api;
import '../../../sdk.dart' as sdk;

Expand All @@ -6,7 +8,11 @@ import '../../../sdk.dart' as sdk;
class NoopTracer implements api.Tracer {
@override
api.Span startSpan(String name,
{api.Context context, List<api.Attribute> attributes}) {
{api.Context context,
api.SpanKind kind,
List<api.Attribute> attributes,
List<api.SpanLink> links,
Int64 startTime}) {
final parentContext = context.spanContext;

return api.NonRecordingSpan(
Expand Down
4 changes: 3 additions & 1 deletion lib/src/api/trace/sampler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ abstract class Sampler {
api.Context context,
api.TraceId traceId,
String spanName,
api.SpanKind spanKind,
bool spanIsRemote, // ignore: avoid_positional_boolean_parameters
List<api.Attribute> spanAttributes);
List<api.Attribute> spanAttributes,
List<api.SpanLink> spanLinks);
Copy link
Contributor

Choose a reason for hiding this comment

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

should we make the args to this named parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We also have all of the spec-"required" parameters in the signature now. If we're looking to avoid breaking API, I'd be in favor of using named parameters for additional parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

these parameters are required

Well, excepting spanIsRemote, which isn't in the spec at all. I suspect that SpanKind is intended to fulfill that role. Should we then make spanIsRemote a named parameter for the possibility that it's removed once we do the work to actually start using SpanKind for things? It's hard to say.

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps remove spanIsRemote?


String get description;
}
10 changes: 9 additions & 1 deletion lib/src/api/trace/span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'package:fixnum/fixnum.dart';

import '../../../api.dart' as api;

enum SpanKind { server, client, producer, consumer, internal }

/// A representation of a single operation within a trace.
///
/// Examples of a span might include remote procedure calls or in-process
Expand All @@ -26,12 +28,15 @@ abstract class Span {
api.SpanId get parentSpanId;

/// The name of the span.
String get name;
String name;

/// Whether this Span is recording information like events with the
/// addEvent operation, status with setStatus, etc.
bool get isRecording;

/// The kind of the span.
SpanKind get kind;

/// Sets the status to the [Span].
///
/// If used, this will override the default [Span] status. Default status code
Expand All @@ -56,6 +61,9 @@ abstract class Span {
/// Retrieve the instrumentation library on this span.
api.InstrumentationLibrary get instrumentationLibrary;

/// Record metadata about an event occurring during this span.
void addEvent(String name, Int64 timestamp, {api.Attributes attributes});
michaelyeager-wf marked this conversation as resolved.
Show resolved Hide resolved

/// Marks the end of this span's execution.
void end();

Expand Down
13 changes: 13 additions & 0 deletions lib/src/api/trace/span_link.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import '../../../api.dart' as api;

class SpanLink {
final api.SpanContext _context;
final List<api.Attribute> _attributes;

SpanLink(this._context, {List<api.Attribute> attributes})
: _attributes = attributes ?? [];

List<api.Attribute> get attributes => _attributes;

api.SpanContext get context => _context;
}
16 changes: 14 additions & 2 deletions lib/src/api/trace/trace_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ abstract class TraceState {
/// Retrieve a value from the TraceState for a given key.
String get(String key);

/// Adds a key value pairs to the TraceState.
/// Adds a key value pair to the TraceState.
///
/// Key is an opaque string up to 256 characters printable. It MUST begin
/// with a lowercase letter, and can only contain lowercase letters a-z,
Expand All @@ -18,9 +18,21 @@ abstract class TraceState {
/// characters (i.e., the range 0x20 to 0x7E) except comma , and =.
void put(String key, String value);

/// Removes a key value pairs from the TraceState.
michaelyeager-wf marked this conversation as resolved.
Show resolved Hide resolved
///
/// Key is an opaque string up to 256 characters printable. It MUST begin
/// with a lowercase letter, and can only contain lowercase letters a-z,
/// digits 0-9, underscores _, dashes -, asterisks *, and forward slashes /.
/// For multi-tenant vendor scenarios, an at sign (@) can be used to prefix
/// the vendor name. The tenant id (before the '@') is limited to 240
/// characters and the vendor id is limited to 13 characters. If in the
/// multi-tenant vendor format, then the first character may additionally
/// be numeric.
void remove(String key);

/// The number of key/value pairs contained in this TraceState.
int get size;

/// Whether this TraceState is emtpy.
/// Whether this TraceState is empty.
bool get isEmpty;
}
8 changes: 7 additions & 1 deletion lib/src/api/trace/tracer.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:fixnum/fixnum.dart';

import '../../../api.dart' as api;

/// An interface for creating [api.Span]s and propagating context in-process.
Expand All @@ -8,5 +10,9 @@ abstract class Tracer {
/// Starts a new [api.Span] without setting it as the current span in this
/// tracer's context.
api.Span startSpan(String name,
{api.Context context, List<api.Attribute> attributes});
{api.Context context,
api.SpanKind kind,
List<api.Attribute> attributes,
List<api.SpanLink> links,
Int64 startTime});
}
5 changes: 5 additions & 0 deletions lib/src/sdk/trace/exporters/collector_exporter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ class CollectorExporter implements api.SpanExporter {
return pb_common.AnyValue();
}

@override
void forceFlush() {
throw UnimplementedError();
}

@override
void shutdown() {
_isShutdown = true;
Expand Down
5 changes: 5 additions & 0 deletions lib/src/sdk/trace/exporters/console_exporter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class ConsoleExporter implements SpanExporter {
_printSpans(spans);
}

@override
void forceFlush() {
throw UnimplementedError();
}

@override
void shutdown() {
_isShutdown = true;
Expand Down
10 changes: 8 additions & 2 deletions lib/src/sdk/trace/samplers/always_off_sampler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ class AlwaysOffSampler implements api.Sampler {
String get description => 'AlwaysOffSampler';

@override
api.SamplingResult shouldSample(api.Context context, api.TraceId traceId,
String spanName, bool spanIsRemote, List<api.Attribute> spanAttributes) {
api.SamplingResult shouldSample(
api.Context context,
api.TraceId traceId,
String spanName,
api.SpanKind spanKind,
bool spanIsRemote,
List<api.Attribute> spanAttributes,
List<api.SpanLink> links) {
return sdk.SamplingResult(api.Decision.drop, spanAttributes,
context.spanContext?.traceState ?? sdk.TraceState.empty());
}
Expand Down
10 changes: 8 additions & 2 deletions lib/src/sdk/trace/samplers/always_on_sampler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ class AlwaysOnSampler implements api.Sampler {
String get description => 'AlwaysOnSampler';

@override
api.SamplingResult shouldSample(api.Context context, api.TraceId traceId,
String spanName, bool spanIsRemote, List<api.Attribute> spanAttributes) {
api.SamplingResult shouldSample(
api.Context context,
api.TraceId traceId,
String spanName,
api.SpanKind spanKind,
bool spanIsRemote,
List<api.Attribute> spanAttributes,
List<api.SpanLink> spanLinks) {
return sdk.SamplingResult(api.Decision.recordAndSample, spanAttributes,
context.spanContext?.traceState ?? sdk.TraceState.empty());
}
Expand Down
36 changes: 21 additions & 15 deletions lib/src/sdk/trace/samplers/parent_based_sampler.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '../../../../sdk.dart' as sdk;
import '../../../../api.dart' as api;
import '../../../../sdk.dart' as sdk;

class ParentBasedSampler implements api.Sampler {
final api.Sampler _root;
Expand All @@ -24,29 +24,35 @@ class ParentBasedSampler implements api.Sampler {
String get description => 'ParentBasedSampler{root=${_root.description}}';

@override
api.SamplingResult shouldSample(api.Context context, api.TraceId traceId,
String spanName, bool spanIsRemote, List<api.Attribute> spanAttributes) {
api.SamplingResult shouldSample(
api.Context context,
api.TraceId traceId,
String spanName,
api.SpanKind spanKind,
bool spanIsRemote,
List<api.Attribute> spanAttributes,
List<api.SpanLink> spanLinks) {
final parentSpanContext = context.spanContext;

if (parentSpanContext == null || !parentSpanContext.isValid) {
return _root.shouldSample(
context, traceId, spanName, spanIsRemote, spanAttributes);
return _root.shouldSample(context, traceId, spanName, spanKind,
spanIsRemote, spanAttributes, spanLinks);
}

if (parentSpanContext.isRemote) {
return ((parentSpanContext.traceFlags & api.TraceFlags.sampled) ==
api.TraceFlags.sampled)
? _remoteParentSampled.shouldSample(
context, traceId, spanName, spanIsRemote, spanAttributes)
: _remoteParentNotSampled.shouldSample(
context, traceId, spanName, spanIsRemote, spanAttributes);
? _remoteParentSampled.shouldSample(context, traceId, spanName,
spanKind, spanIsRemote, spanAttributes, spanLinks)
: _remoteParentNotSampled.shouldSample(context, traceId, spanName,
spanKind, spanIsRemote, spanAttributes, spanLinks);
}

return ((parentSpanContext.traceFlags & api.TraceFlags.sampled) ==
api.TraceFlags.sampled)
? _localParentSampled.shouldSample(
context, traceId, spanName, spanIsRemote, spanAttributes)
: _localParentNotSampled.shouldSample(
context, traceId, spanName, spanIsRemote, spanAttributes);
return (parentSpanContext.traceFlags & api.TraceFlags.sampled) ==
api.TraceFlags.sampled
? _localParentSampled.shouldSample(context, traceId, spanName, spanKind,
spanIsRemote, spanAttributes, spanLinks)
: _localParentNotSampled.shouldSample(context, traceId, spanName,
spanKind, spanIsRemote, spanAttributes, spanLinks);
}
}
25 changes: 21 additions & 4 deletions lib/src/sdk/trace/span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import '../../../sdk.dart' as sdk;
class Span implements api.Span {
final api.SpanContext _spanContext;
final api.SpanId _parentSpanId;
final api.SpanKind _kind; // ignore: unused_field
final api.SpanStatus _status = api.SpanStatus();
final List<api.SpanProcessor> _processors;
final List<api.SpanLink> _links; // ignore: unused_field
final api.Resource _resource;
sdk.SpanLimits _spanLimits = sdk.SpanLimits();
final api.InstrumentationLibrary _instrumentationLibrary;
Int64 _startTime;
final Int64 _startTime;
Int64 _endTime;
int _droppedSpanAttributes = 0;
final api.Attributes attributes = api.Attributes.empty();
Expand All @@ -26,9 +28,15 @@ class Span implements api.Span {
/// Construct a [Span].
Span(this.name, this._spanContext, this._parentSpanId, this._processors,
this._resource, this._instrumentationLibrary,
{List<api.Attribute> attributes, sdk.SpanLimits spanlimits}) {
_startTime = Int64(DateTime.now().toUtc().microsecondsSinceEpoch);

{api.SpanKind kind,
List<api.Attribute> attributes,
List<api.SpanLink> links,
sdk.SpanLimits spanlimits,
Int64 startTime})
: _links = links ?? [],
_kind = kind ?? api.SpanKind.internal,
_startTime =
startTime ?? Int64(DateTime.now().toUtc().microsecondsSinceEpoch) {
if (spanlimits != null) _spanLimits = spanlimits;

if (attributes != null) {
Expand Down Expand Up @@ -149,6 +157,15 @@ class Span implements api.Span {
]);
}

@override
api.SpanKind get kind => _kind;

@override
void addEvent(String name, Int64 timestamp, {api.Attributes attributes}) {
michaelyeager-wf marked this conversation as resolved.
Show resolved Hide resolved
// TODO: O11Y-1531
throw UnimplementedError();
}

//Truncate just strings which length is longer than configuration.
//Reference: https://github.com/open-telemetry/opentelemetry-java/blob/14ffacd1cdd22f5aa556eeda4a569c7f144eadf2/sdk/common/src/main/java/io/opentelemetry/sdk/internal/AttributeUtil.java#L80
static String _applyAttributeLengthLimit(String value, int lengthLimit) {
Expand Down
22 changes: 21 additions & 1 deletion lib/src/sdk/trace/trace_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class TraceState implements api.TraceState {
@override
String get(String key) => _state[key];

/// Adds a key value pairs to the TraceState.
/// Adds a key value pair to the TraceState.
///
/// Key is an opaque string up to 256 characters printable. It MUST begin
/// with a lowercase letter, and can only contain lowercase letters a-z,
Expand All @@ -94,6 +94,26 @@ class TraceState implements api.TraceState {
}
}

/// Removes a key value pair from the TraceState.
///
/// Key is an opaque string up to 256 characters printable. It MUST begin
/// with a lowercase letter, and can only contain lowercase letters a-z,
/// digits 0-9, underscores _, dashes -, asterisks *, and forward slashes /.
/// For multi-tenant vendor scenarios, an at sign (@) can be used to prefix
/// the vendor name. The tenant id (before the '@') is limited to 240
/// characters and the vendor id is limited to 13 characters. If in the
/// multi-tenant vendor format, then the first character may additionally
/// be numeric.
///
/// Value is opaque string up to 256 characters printable ASCII RFC0020
/// characters (i.e., the range 0x20 to 0x7E) except comma , and =.
@override
void remove(String key) {
if (_isValidKey(key)) {
_state.remove(key);
}
}

@override
String toString() {
if (isEmpty) {
Expand Down
Loading