Skip to content

Commit

Permalink
Add Span API. (open-telemetry#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
g-easy authored Feb 25, 2020
1 parent 573696f commit 3cc2c69
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 11 deletions.
137 changes: 137 additions & 0 deletions api/include/opentelemetry/trace/canonical_code.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#pragma once

#include <cstdint>

namespace opentelemetry
{
namespace trace
{
enum class CanonicalCode : uint8_t
{
/**
* The operation completed successfully.
*/
OK = 0,

/**
* The operation was cancelled (typically by the caller).
*/
CANCELLED = 1,

/**
* Unknown error. An example of where this error may be returned is if a Status value received
* from another address space belongs to an error-space that is not known in this address space.
* Also errors raised by APIs that do not return enough error information may be converted to
* this error.
*/
UNKNOWN = 2,

/**
* Client specified an invalid argument. Note that this differs from FAILED_PRECONDITION.
* INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the
* system (e.g., a malformed file name).
*/
INVALID_ARGUMENT = 3,

/**
* Deadline expired before operation could complete. For operations that change the state of the
* system, this error may be returned even if the operation has completed successfully. For
* example, a successful response from a server could have been delayed long enough for the
* deadline to expire.
*/
DEADLINE_EXCEEDED = 4,

/**
* Some requested entity (e.g., file or directory) was not found.
*/
NOT_FOUND = 5,

/**
* Some entity that we attempted to create (e.g., file or directory) already exists.
*/
ALREADY_EXISTS = 6,

/**
* The caller does not have permission to execute the specified operation. PERMISSION_DENIED
* must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED
* instead for those errors). PERMISSION_DENIED must not be used if the caller cannot be
* identified (use UNAUTHENTICATED instead for those errors).
*/
PERMISSION_DENIED = 7,

/**
* Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system
* is out of space.
*/
RESOURCE_EXHAUSTED = 8,

/**
* Operation was rejected because the system is not in a state required for the operation's
* execution. For example, directory to be deleted may be non-empty, an rmdir operation is
* applied to a non-directory, etc.
*
* A litmus test that may help a service implementor in deciding between FAILED_PRECONDITION,
* ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call.
* (b) Use ABORTED if the client should retry at a higher-level (e.g., restarting a
* read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until
* the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory
* is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless
* they have first fixed up the directory by deleting files from it.
*/
FAILED_PRECONDITION = 9,

/**
* The operation was aborted, typically due to a concurrency issue like sequencer check
* failures, transaction aborts, etc.
*
* See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.
*/
ABORTED = 10,

/**
* Operation was attempted past the valid range. E.g., seeking or reading past end of file.
*
* Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system
* state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to
* read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if
* asked to read from an offset past the current file size.
*
* There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend
* using OUT_OF_RANGE (the more specific error) when it applies so that callers who are
* iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are
* done.
*/
OUT_OF_RANGE = 11,

/**
* Operation is not implemented or not supported/enabled in this service.
*/
UNIMPLEMENTED = 12,

/**
* Internal errors. Means some invariants expected by underlying system has been broken. If you
* see one of these errors, something is very broken.
*/
INTERNAL = 13,

/**
* The service is currently unavailable. This is a most likely a transient condition and may be
* corrected by retrying with a backoff.
*
* See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.
*/
UNAVAILABLE = 14,

/**
* Unrecoverable data loss or corruption.
*/
DATA_LOSS = 15,

/**
* The request does not have valid authentication credentials for the operation.
*/
UNAUTHENTICATED = 16,
};

} // namespace trace
} // namespace opentelemetry
25 changes: 22 additions & 3 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#pragma once
// Please refer to provider.h for documentation on how to obtain a Tracer object.
//
// This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be
// used directly. Please refer to span.h and tracer.h for documentation on these interfaces.

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/tracer.h"

#include <memory>
Expand All @@ -9,22 +16,34 @@ namespace opentelemetry
namespace trace
{
/**
* Noop implementation of Span.
* No-op implementation of Span. This class should not be used directly.
*/
class NoopSpan final : public Span
{
public:
explicit NoopSpan(const std::shared_ptr<Tracer> &tracer) noexcept : tracer_{tracer} {}

// Span
void AddEvent(nostd::string_view name) noexcept override {}

void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override {}
void AddEvent(nostd::string_view name, core::SteadyTimestamp timestamp) noexcept override {}

void SetStatus(CanonicalCode code, nostd::string_view description) noexcept override {}

void UpdateName(nostd::string_view name) noexcept override {}

void End() noexcept override {}

bool IsRecording() const noexcept override { return false; }

Tracer &tracer() const noexcept override { return *tracer_; }

private:
std::shared_ptr<Tracer> tracer_;
};

/**
* Noop implementation of Tracer
* No-op implementation of Tracer.
*/
class NoopTracer final : public Tracer, public std::enable_shared_from_this<NoopTracer>
{
Expand Down
89 changes: 81 additions & 8 deletions api/include/opentelemetry/trace/span.h
Original file line number Diff line number Diff line change
@@ -1,38 +1,111 @@
#pragma once

#include <cstdint>

#include "opentelemetry/core/timestamp.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/trace/canonical_code.h"

namespace opentelemetry
{
namespace trace
{
enum class SpanKind
{
kInternal,
kServer,
kClient,
kProducer,
kConsumer,
};
/**
* StartSpanOptions provides options to set properties of span at the time of starting a new span.
* StartSpanOptions provides options to set properties of a Span at the time of its creation
*/
struct StartSpanOptions
{
// Sets the start time of a span.
// Optionally sets the start time of a Span.
//
// If the start time of a span is set, timestamps from both the system clock and steady clock
// should be provided.
// If the start time of a Span is set, timestamps from both the system clock and steady clock
// must be provided.
//
// Timestamps from the steady clock can be used to most accurately measure a span's
// duration, while timestamps from the system clock can be used to most accurately place a span's
// time point relative to other spans collected across a distributed system.
// Timestamps from the steady clock can be used to most accurately measure a Span's
// duration, while timestamps from the system clock can be used to most accurately place a Span's
// time point relative to other Spans collected across a distributed system.
core::SystemTimestamp start_system_time;
core::SteadyTimestamp start_steady_time;

// TODO:
// Span(Context?) parent;
// SpanContext remote_parent;
// Links
// Attributes
SpanKind kind = SpanKind::kInternal;
};

class Tracer;

/**
* A span represents a single operation within a trace.
* A Span represents a single operation within a Trace.
*/
class Span
{
public:
// Note that Spans should be created using the Tracer class. Please refer to
// tracer.h for documentation.
Span() = default;

// The Span destructor End()s the Span, if it hasn't been ended already.
virtual ~Span() = default;

// Not copiable or movable.
Span(const Span &) = delete;
Span(Span &&) = delete;
Span &operator=(const Span &) = delete;
Span &operator=(Span &&) = delete;

// TODO
// Sets an attribute on the Span. If the Span previously contained a mapping for
// the key, the old value is replaced.
//
// If an empty string is used as the value, the attribute will be silently
// dropped. Note: this behavior could change in the future.
// virtual void SetAttribute(nostd::string_view key, AttributeValue&& value) = 0;

// Adds an event to the Span.
virtual void AddEvent(nostd::string_view name) noexcept = 0;

// Adds an event to the Span, with a custom timestamp.
virtual void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept = 0;
virtual void AddEvent(nostd::string_view name, core::SteadyTimestamp timestamp) noexcept = 0;

// TODO
// Adds an event to the Span, with a custom timestamp, and attributes.
// virtual void AddEvent(nostd::string_view name, core::SteadyTimestamp
// timestamp, nostd::span<const std::pair<nostd::string_view name, AttributeValue
// value>> attributes) noexcept = 0;

// Sets the status of the span. The default status is OK. Only the value of the last call will be
// recorded, and implementations are free to ignore previous calls.
virtual void SetStatus(CanonicalCode code, nostd::string_view description) noexcept = 0;

// Updates the name of the Span. If used, this will override the name provided
// during creation.
virtual void UpdateName(nostd::string_view name) noexcept = 0;

// Mark the end of the Span. Only the timing of the first End call for a given Span will
// be recorded, and implementations are free to ignore all further calls.
virtual void End() noexcept = 0;

// TODO
// virtual void End(EndSpanOptions&& opts) noexcept = 0;

// TODO
// SpanContext context() const noexcept = 0;

// Returns true if this Span is recording tracing events (e.g. SetAttribute,
// AddEvent).
virtual bool IsRecording() const noexcept = 0;

virtual Tracer &tracer() const noexcept = 0;
};
} // namespace trace
Expand Down

0 comments on commit 3cc2c69

Please sign in to comment.