From b837c9f6278fbace77b4d60acb540209f50aac37 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 26 Sep 2019 13:40:42 -0700 Subject: [PATCH 01/31] Span add override parameters for start_time and end_time --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 4 ++-- .../src/opentelemetry/sdk/trace/__init__.py | 8 ++++++-- opentelemetry-sdk/tests/trace/test_trace.py | 10 ++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index b79cdeb4df..55cdc567d5 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -142,7 +142,7 @@ class SpanKind(enum.Enum): class Span: """A span represents a single operation within a trace.""" - def start(self) -> None: + def start(self, start_time: int = None) -> None: """Sets the current time as the span's start time. Each span represents a single operation. The span's start time is the @@ -152,7 +152,7 @@ def start(self) -> None: implementations are free to ignore or raise on further calls. """ - def end(self) -> None: + def end(self, end_time: int = None) -> None: """Sets the current time as the span's end time. The span's end time is the wall time at which the operation finished. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index a694476e1f..37f9c35e07 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -340,19 +340,21 @@ def add_lazy_link(self, link: "trace_api.Link") -> None: return self.links.append(link) - def start(self): + def start(self, start_time: int = None): with self._lock: if not self.is_recording_events(): return has_started = self.start_time is not None if not has_started: self.start_time = util.time_ns() + if start_time is not None : + self.start_time = start_time if has_started: logger.warning("Calling start() on a started span.") return self.span_processor.on_start(self) - def end(self): + def end(self, end_time: int = None): with self._lock: if not self.is_recording_events(): return @@ -361,6 +363,8 @@ def end(self): has_ended = self.end_time is not None if not has_ended: self.end_time = util.time_ns() + if end_time is not None: + self.end_time = end_time if has_ended: logger.warning("Calling end() on an ended span.") return diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 0570affc41..378534453c 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -234,6 +234,16 @@ def test_start_span(self): span.start() self.assertEqual(start_time, span.start_time) + def test_span_override_start_and_end_time(self): + """Span sending custom start_time and end_time values""" + span = trace.Span("name", mock.Mock(spec=trace_api.SpanContext)) + start_time = 123 + span.start(start_time) + self.assertEqual(start_time, span.start_time) + end_time = 456 + span.end(end_time) + self.assertEqual(end_time, span.end_time) + def test_ended_span(self): """"Events, attributes are not allowed after span is ended""" tracer = trace.Tracer("test_ended_span") From a12fe5dab59cc38414e8e6795f4de9ffd0c694ee Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 26 Sep 2019 16:26:00 -0700 Subject: [PATCH 02/31] Make lint happy --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 37f9c35e07..e844bfcf94 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -347,7 +347,7 @@ def start(self, start_time: int = None): has_started = self.start_time is not None if not has_started: self.start_time = util.time_ns() - if start_time is not None : + if start_time is not None: self.start_time = start_time if has_started: logger.warning("Calling start() on a started span.") From 276ecb4138ac1a772be41c5fd35b8d3ddec9a1ad Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 27 Sep 2019 11:27:19 -0700 Subject: [PATCH 03/31] Addressing comments --- .../src/opentelemetry/sdk/trace/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index e844bfcf94..1e1594e348 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -346,9 +346,10 @@ def start(self, start_time: int = None): return has_started = self.start_time is not None if not has_started: - self.start_time = util.time_ns() - if start_time is not None: - self.start_time = start_time + if start_time is not None: + self.start_time = start_time + else: + self.start_time = util.time_ns() if has_started: logger.warning("Calling start() on a started span.") return @@ -362,9 +363,10 @@ def end(self, end_time: int = None): raise RuntimeError("Calling end() on a not started span.") has_ended = self.end_time is not None if not has_ended: - self.end_time = util.time_ns() - if end_time is not None: - self.end_time = end_time + if end_time is not None: + self.end_time = end_time + else: + self.end_time = util.time_ns() if has_ended: logger.warning("Calling end() on an ended span.") return From 2b90351052f8edb389be395a88e0fa38b606079d Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 27 Sep 2019 14:10:59 -0700 Subject: [PATCH 04/31] Addressing comments --- .../src/opentelemetry/sdk/trace/__init__.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 1e1594e348..2362014681 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -346,10 +346,7 @@ def start(self, start_time: int = None): return has_started = self.start_time is not None if not has_started: - if start_time is not None: - self.start_time = start_time - else: - self.start_time = util.time_ns() + self.start_time = start_time or util.time_ns() if has_started: logger.warning("Calling start() on a started span.") return @@ -363,10 +360,7 @@ def end(self, end_time: int = None): raise RuntimeError("Calling end() on a not started span.") has_ended = self.end_time is not None if not has_ended: - if end_time is not None: - self.end_time = end_time - else: - self.end_time = util.time_ns() + self.end_time = end_time or util.time_ns() if has_ended: logger.warning("Calling end() on an ended span.") return From eccef1a9686f2527335cfe5b18e22a1e79e84b90 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 27 Sep 2019 17:06:21 -0700 Subject: [PATCH 05/31] Allowing 0 as start and end time --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 2362014681..d24955d163 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -346,7 +346,7 @@ def start(self, start_time: int = None): return has_started = self.start_time is not None if not has_started: - self.start_time = start_time or util.time_ns() + self.start_time = start_time if start_time is not None else util.time_ns() if has_started: logger.warning("Calling start() on a started span.") return @@ -360,7 +360,7 @@ def end(self, end_time: int = None): raise RuntimeError("Calling end() on a not started span.") has_ended = self.end_time is not None if not has_ended: - self.end_time = end_time or util.time_ns() + self.end_time = end_time if end_time is not None else util.time_ns() if has_ended: logger.warning("Calling end() on an ended span.") return From a187fec187ce06bcf78bfbd64195cfba783a31cd Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 27 Sep 2019 17:16:43 -0700 Subject: [PATCH 06/31] Fix lint issues --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index d24955d163..37294ee05f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -346,7 +346,9 @@ def start(self, start_time: int = None): return has_started = self.start_time is not None if not has_started: - self.start_time = start_time if start_time is not None else util.time_ns() + self.start_time = ( + start_time if start_time is not None else util.time_ns() + ) if has_started: logger.warning("Calling start() on a started span.") return @@ -360,7 +362,9 @@ def end(self, end_time: int = None): raise RuntimeError("Calling end() on a not started span.") has_ended = self.end_time is not None if not has_ended: - self.end_time = end_time if end_time is not None else util.time_ns() + self.end_time = ( + end_time if end_time is not None else util.time_ns() + ) if has_ended: logger.warning("Calling end() on an ended span.") return From 77d364946040ea6125c8028933edf1702fc49960 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 8 Oct 2019 11:59:29 -0700 Subject: [PATCH 07/31] Add code coverage --- .codecov.yml | 5 +++++ .gitignore | 1 + .travis.yml | 8 ++++++++ tox.ini | 5 ++++- 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000000..7719477819 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,5 @@ +fixes: + - "^.*/site-packages/opentelemetry/sdk/::opentelemetry-sdk/src/opentelemetry/sdk/" + - "^.*/site-packages/opentelemetry/ext/wsgi/::ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/" + - "^.*/site-packages/opentelemetry/ext/http_requests/::ext/opentelemetry-ext-http-requests/src/opentelemetry/ext/http_requests/" + - "^.*/site-packages/opentelemetry/::opentelemetry-api/src/opentelemetry/" diff --git a/.gitignore b/.gitignore index 679b6fd0cc..9a72cbf8ce 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ pip-log.txt .tox .cache htmlcov +coverage.xml # Translations *.mo diff --git a/.travis.yml b/.travis.yml index 64eebc3621..6e5c9e2039 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,3 +19,11 @@ install: script: - tox + +after_success: + - pip install codecov + - codecov -v --file + opentelemetry-api/tests/coverage.xml + opentelemetry-sdk/tests/coverage.xml + ext/opentelemetry-ext-wsgi/tests/coverage.xml + ext/opentelemetry-ext-http-requests/tests/coverage.xml \ No newline at end of file diff --git a/tox.ini b/tox.ini index 0db2364f19..268fe4e487 100644 --- a/tox.ini +++ b/tox.ini @@ -15,6 +15,7 @@ python = [testenv] deps = mypy,mypyinstalled: mypy~=0.711 + test: coverage setenv = mypy: MYPYPATH={toxinidir}/opentelemetry-api/src/ @@ -47,7 +48,9 @@ commands_pre = mypyinstalled: pip install file://{toxinidir}/opentelemetry-api/ commands = - test: python -m unittest discover + test: coverage run --source {envsitepackagesdir}/opentelemetry -m unittest discover + test: coverage report + test: coverage xml mypy: mypy --namespace-packages opentelemetry-api/src/opentelemetry/ ; For test code, we don't want to enforce the full mypy strictness From f3af20fbbdd55ad7f24488a4cb9c4fab7668a955 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Wed, 9 Oct 2019 13:15:43 -0700 Subject: [PATCH 08/31] Revert latest commit --- .codecov.yml | 5 ----- .gitignore | 1 - .travis.yml | 8 -------- tox.ini | 5 +---- 4 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index 7719477819..0000000000 --- a/.codecov.yml +++ /dev/null @@ -1,5 +0,0 @@ -fixes: - - "^.*/site-packages/opentelemetry/sdk/::opentelemetry-sdk/src/opentelemetry/sdk/" - - "^.*/site-packages/opentelemetry/ext/wsgi/::ext/opentelemetry-ext-wsgi/src/opentelemetry/ext/wsgi/" - - "^.*/site-packages/opentelemetry/ext/http_requests/::ext/opentelemetry-ext-http-requests/src/opentelemetry/ext/http_requests/" - - "^.*/site-packages/opentelemetry/::opentelemetry-api/src/opentelemetry/" diff --git a/.gitignore b/.gitignore index 9a72cbf8ce..679b6fd0cc 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ pip-log.txt .tox .cache htmlcov -coverage.xml # Translations *.mo diff --git a/.travis.yml b/.travis.yml index 6e5c9e2039..64eebc3621 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,11 +19,3 @@ install: script: - tox - -after_success: - - pip install codecov - - codecov -v --file - opentelemetry-api/tests/coverage.xml - opentelemetry-sdk/tests/coverage.xml - ext/opentelemetry-ext-wsgi/tests/coverage.xml - ext/opentelemetry-ext-http-requests/tests/coverage.xml \ No newline at end of file diff --git a/tox.ini b/tox.ini index 268fe4e487..0db2364f19 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,6 @@ python = [testenv] deps = mypy,mypyinstalled: mypy~=0.711 - test: coverage setenv = mypy: MYPYPATH={toxinidir}/opentelemetry-api/src/ @@ -48,9 +47,7 @@ commands_pre = mypyinstalled: pip install file://{toxinidir}/opentelemetry-api/ commands = - test: coverage run --source {envsitepackagesdir}/opentelemetry -m unittest discover - test: coverage report - test: coverage xml + test: python -m unittest discover mypy: mypy --namespace-packages opentelemetry-api/src/opentelemetry/ ; For test code, we don't want to enforce the full mypy strictness From e54a0535ac833a1df4615a70af9faa51c6a0540f Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Wed, 9 Oct 2019 16:07:39 -0700 Subject: [PATCH 09/31] Adding setStatus in Span --- .../src/opentelemetry/trace/__init__.py | 31 +++++++++++++++++++ .../src/opentelemetry/sdk/trace/__init__.py | 31 +++++++++++++++++++ opentelemetry-sdk/tests/trace/test_trace.py | 10 ++++++ 3 files changed, 72 insertions(+) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 18eced4504..9d496d82ec 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -139,6 +139,33 @@ class SpanKind(enum.Enum): CONSUMER = 4 +class SpanStatus: + """Represents the status of a finished Span """ + + def get_canonical_code(self) -> int: + """Gets the status CanonicalCode. + StatusCanonicalCode represents the canonical set of status codes of a finished Span, following the Standard GRPC codes + https://github.com/grpc/grpc/blob/master/doc/statuscodes.md + + Returns: + A number representing the CanonicalCode + """ + + def get_description(self) -> str: + """Gets the status description. + + Returns: + Returns the description of the Status. + """ + + def get_is_ok(self) -> bool: + """Gets the status is ok flag. + + Returns: + Returns false if this Status represents an error, else returns true. + """ + + class Span: """A span represents a single operation within a trace.""" @@ -226,6 +253,10 @@ def is_recording_events(self) -> bool: events with the add_event operation and attributes using set_attribute. """ + def set_status(self, status: SpanStatus) -> None: + """Sets the Status of the Span. If used, this will override the default Span status, which is OK. + """ + class TraceOptions(int): """A bitmask that represents options specific to the trace. diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index eb754fadb8..17cb91532d 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -94,6 +94,32 @@ def shutdown(self) -> None: sp.shutdown() +class SpanStatus(trace_api.SpanStatus): + """See `opentelemetry.trace.SpanStatus`. + + Represents the status of a finished Span + + Args: + canonical_code: Represents the canonical set of status codes of a finished Span, following the Standard GRPC codes + description: Description of this Status + is_ok: Use to determine if the span was an error or not + """ + + def __init__(self, canonical_code=0, description=None, is_ok=True): + self.canonical_code = canonical_code + self.description = description + self.is_ok = is_ok + + def get_canonical_code(self) -> bool: + return self.canonical_code + + def get_description(self) -> bool: + return self.description + + def get_is_ok(self) -> bool: + return self.is_ok + + class Span(trace_api.Span): """See `opentelemetry.trace.Span`. @@ -132,6 +158,7 @@ def __init__( links: typing.Sequence[trace_api.Link] = None, # TODO kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, span_processor: SpanProcessor = SpanProcessor(), + status: SpanStatus = SpanStatus(), ) -> None: self.name = name @@ -141,6 +168,7 @@ def __init__( self.trace_config = trace_config self.resource = resource self.kind = kind + self.status = status self.span_processor = span_processor self._lock = threading.Lock() @@ -285,6 +313,9 @@ def update_name(self, name: str) -> None: def is_recording_events(self) -> bool: return True + def set_status(self, status: trace_api.SpanStatus) -> None: + self.status = status + def generate_span_id() -> int: """Get a new random span ID. diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index dc593a9d62..16bb214bf8 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -223,6 +223,16 @@ def test_span_members(self): root.update_name("toor") self.assertEqual(root.name, "toor") + # default status + self.assertEqual(root.status.get_is_ok(), True) + self.assertEqual(root.status.get_canonical_code(), 0) + self.assertEqual(root.status.get_description(), None) + + # status + newStatus = trace.SpanStatus(2, "Test description", False) + root.set_status(newStatus) + self.assertEqual(root.status, newStatus) + def test_start_span(self): """Start twice, end a not started""" span = trace.Span("name", mock.Mock(spec=trace_api.SpanContext)) From 174ac9080d9f1681037b43195d2096de4c6d0659 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Wed, 9 Oct 2019 16:27:52 -0700 Subject: [PATCH 10/31] Fixing lint issues --- .../src/opentelemetry/trace/__init__.py | 2 +- opentelemetry-sdk/tests/trace/test_trace.py | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 9d496d82ec..53044fd634 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -160,7 +160,7 @@ def get_description(self) -> str: def get_is_ok(self) -> bool: """Gets the status is ok flag. - + Returns: Returns false if this Status represents an error, else returns true. """ diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 16bb214bf8..2a297ae0e8 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -223,16 +223,6 @@ def test_span_members(self): root.update_name("toor") self.assertEqual(root.name, "toor") - # default status - self.assertEqual(root.status.get_is_ok(), True) - self.assertEqual(root.status.get_canonical_code(), 0) - self.assertEqual(root.status.get_description(), None) - - # status - newStatus = trace.SpanStatus(2, "Test description", False) - root.set_status(newStatus) - self.assertEqual(root.status, newStatus) - def test_start_span(self): """Start twice, end a not started""" span = trace.Span("name", mock.Mock(spec=trace_api.SpanContext)) @@ -245,6 +235,16 @@ def test_start_span(self): span.start() self.assertEqual(start_time, span.start_time) + # default status + self.assertEqual(span.status.get_is_ok(), True) + self.assertEqual(span.status.get_canonical_code(), 0) + self.assertEqual(span.status.get_description(), None) + + # status + new_status = trace.SpanStatus(2, "Test description", False) + span.set_status(new_status) + self.assertEqual(span.status, new_status) + def test_span_override_start_and_end_time(self): """Span sending custom start_time and end_time values""" span = trace.Span("name", mock.Mock(spec=trace_api.SpanContext)) From 2015944151f0dae7bed061134db30fd6d47b07da Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 10 Oct 2019 14:02:00 -0700 Subject: [PATCH 11/31] Addressing comments --- .../src/opentelemetry/trace/__init__.py | 112 +++++++++++++++--- .../src/opentelemetry/sdk/trace/__init__.py | 31 +---- opentelemetry-sdk/tests/trace/test_trace.py | 12 +- 3 files changed, 103 insertions(+), 52 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 53044fd634..e6f0670ff6 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -139,31 +139,105 @@ class SpanKind(enum.Enum): CONSUMER = 4 -class SpanStatus: - """Represents the status of a finished Span """ +class StatusCanonicalCode(enum.Enum): + """Represents the canonical set of status codes of a finished Span, following the Standard GRPC codes. See + https://github.com/open-telemetry/opentelemetry-specification/blob/2dbae9a491224f1fddfa2bb05c2a1a444c623077/specification/api-tracing.md#statuscanonicalcode. + """ - def get_canonical_code(self) -> int: - """Gets the status CanonicalCode. - StatusCanonicalCode represents the canonical set of status codes of a finished Span, following the Standard GRPC codes - https://github.com/grpc/grpc/blob/master/doc/statuscodes.md + #: Not an error; returned on success. + OK = 0 - Returns: - A number representing the CanonicalCode - """ + #: The operation was cancelled, typically by the caller. + CANCELLED = 1 - def get_description(self) -> str: - """Gets the status description. + #: Unknown error. For example, this error may be returned when 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 - Returns: - Returns the description of the Status. - """ + #: The 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 = 2 - def get_is_ok(self) -> bool: - """Gets the status is ok flag. + #: The deadline expired before the 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 + DEADLINE_EXCEEDED = 0 - Returns: - Returns false if this Status represents an error, else returns true. + #: Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist, + # NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used. + NOT_FOUND = 1 + + #: The entity that a client attempted to create (e.g., file or directory) already exists. + ALREADY_EXISTS = 2 + + #: 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 can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or + # satisfies other pre-conditions. + PERMISSION_DENIED = 2 + + #: The request does not have valid authentication credentials for the operation. + UNAUTHENTICATED = 0 + + #: Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. + RESOURCE_EXHAUSTED = 1 + + #: The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. + # Service implementors can use the following guidelines to decide 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., when a client-specified test-and-set fails, indicating the client should restart 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 the files are deleted from the + # directory. + FAILED_PRECONDITION = 2 + + #: The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE. + ABORTED = 2 + + #: The 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 = 0 + + #: The operation is not implemented or is not supported/enabled in this service. + UNIMPLEMENTED = 1 + + #: Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. + INTERNAL = 2 + + #: The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations. + UNAVAILABLE = 2 + + #: Unrecoverable data loss or corruption. + DATA_LOSS = 2 + + +class Status: + """Represents the status of a finished Span + + Args: + canonical_code: Represents the canonical set of status codes of a finished Span + description: Description of the Status + """ + + def __init__( + self, canonical_code=StatusCanonicalCode.OK, description=None + ): + self.code = canonical_code + self.desc = description + + @property + def canonical_code(self) -> StatusCanonicalCode: + """StatusCanonicalCode represents the canonical set of status codes of a finished Span, following the Standard GRPC codes + https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-tracing.md#statuscanonicalcode """ + return self.code + + @property + def description(self) -> str: + """Status description""" + return self.desc + + @property + def is_ok(self) -> bool: + """Returns false if this Status represents an error, else returns true""" + return self.canonical_code == StatusCanonicalCode.OK class Span: @@ -253,7 +327,7 @@ def is_recording_events(self) -> bool: events with the add_event operation and attributes using set_attribute. """ - def set_status(self, status: SpanStatus) -> None: + def set_status(self, status: Status) -> None: """Sets the Status of the Span. If used, this will override the default Span status, which is OK. """ diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 17cb91532d..292553c808 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -94,32 +94,6 @@ def shutdown(self) -> None: sp.shutdown() -class SpanStatus(trace_api.SpanStatus): - """See `opentelemetry.trace.SpanStatus`. - - Represents the status of a finished Span - - Args: - canonical_code: Represents the canonical set of status codes of a finished Span, following the Standard GRPC codes - description: Description of this Status - is_ok: Use to determine if the span was an error or not - """ - - def __init__(self, canonical_code=0, description=None, is_ok=True): - self.canonical_code = canonical_code - self.description = description - self.is_ok = is_ok - - def get_canonical_code(self) -> bool: - return self.canonical_code - - def get_description(self) -> bool: - return self.description - - def get_is_ok(self) -> bool: - return self.is_ok - - class Span(trace_api.Span): """See `opentelemetry.trace.Span`. @@ -158,7 +132,6 @@ def __init__( links: typing.Sequence[trace_api.Link] = None, # TODO kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, span_processor: SpanProcessor = SpanProcessor(), - status: SpanStatus = SpanStatus(), ) -> None: self.name = name @@ -168,9 +141,9 @@ def __init__( self.trace_config = trace_config self.resource = resource self.kind = kind - self.status = status self.span_processor = span_processor + self.status = trace_api.Status() self._lock = threading.Lock() if attributes is None: @@ -313,7 +286,7 @@ def update_name(self, name: str) -> None: def is_recording_events(self) -> bool: return True - def set_status(self, status: trace_api.SpanStatus) -> None: + def set_status(self, status: trace_api.Status) -> None: self.status = status diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 2a297ae0e8..a2a6213c3f 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -236,12 +236,16 @@ def test_start_span(self): self.assertEqual(start_time, span.start_time) # default status - self.assertEqual(span.status.get_is_ok(), True) - self.assertEqual(span.status.get_canonical_code(), 0) - self.assertEqual(span.status.get_description(), None) + self.assertTrue(span.status.is_ok) + self.assertEqual( + span.status.canonical_code, trace_api.StatusCanonicalCode.OK + ) + self.assertIs(span.status.description, None) # status - new_status = trace.SpanStatus(2, "Test description", False) + new_status = trace_api.Status( + trace_api.StatusCanonicalCode.CANCELLED, "Test description" + ) span.set_status(new_status) self.assertEqual(span.status, new_status) From 437b5a51c07975c3411b187e5b36084546f9ada2 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 10 Oct 2019 14:18:37 -0700 Subject: [PATCH 12/31] Fixing mypy issues --- .../src/opentelemetry/trace/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index e6f0670ff6..a8e0760bef 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -209,18 +209,18 @@ class StatusCanonicalCode(enum.Enum): class Status: - """Represents the status of a finished Span + """Represents the status of a finished Span. Args: canonical_code: Represents the canonical set of status codes of a finished Span - description: Description of the Status + description: Description of the Status. """ def __init__( - self, canonical_code=StatusCanonicalCode.OK, description=None + self, canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, description: typing.Optional[str] = None ): - self.code = canonical_code - self.desc = description + self.code: "StatusCanonicalCode" = canonical_code + self.desc: typing.Optional[str] = description @property def canonical_code(self) -> StatusCanonicalCode: @@ -230,7 +230,7 @@ def canonical_code(self) -> StatusCanonicalCode: return self.code @property - def description(self) -> str: + def description(self) -> typing.Optional[str]: """Status description""" return self.desc From 8ae053277912a05afde8d3659d3634c802155c03 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 10 Oct 2019 14:27:38 -0700 Subject: [PATCH 13/31] Fixing old python ver issue --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index a8e0760bef..b9cdeb2e2d 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -219,8 +219,8 @@ class Status: def __init__( self, canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, description: typing.Optional[str] = None ): - self.code: "StatusCanonicalCode" = canonical_code - self.desc: typing.Optional[str] = description + self.code = canonical_code + self.desc = description @property def canonical_code(self) -> StatusCanonicalCode: From 798551b5128278c6731d7f17110917150917baaa Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 10 Oct 2019 14:37:23 -0700 Subject: [PATCH 14/31] Fixing formatting issue --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index b9cdeb2e2d..bd7c7ddc9a 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -217,7 +217,9 @@ class Status: """ def __init__( - self, canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, description: typing.Optional[str] = None + self, + canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, + description: typing.Optional[str] = None, ): self.code = canonical_code self.desc = description From 35a93d4a074697d2f4f4eb14710b41fd75491e53 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Thu, 10 Oct 2019 14:45:46 -0700 Subject: [PATCH 15/31] Fixing issue with trailing whitespace --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index bd7c7ddc9a..9a74cbe503 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -209,7 +209,7 @@ class StatusCanonicalCode(enum.Enum): class Status: - """Represents the status of a finished Span. + """Represents the status of a finished Span Args: canonical_code: Represents the canonical set of status codes of a finished Span From db4501781f8f204436b03976a906610afc2603b6 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 11 Oct 2019 12:20:39 -0700 Subject: [PATCH 16/31] Addressing comments --- .../src/opentelemetry/trace/__init__.py | 110 +----------- .../src/opentelemetry/trace/status.py | 167 ++++++++++++++++++ 2 files changed, 173 insertions(+), 104 deletions(-) create mode 100644 opentelemetry-api/src/opentelemetry/trace/status.py diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 9a74cbe503..067adbe6d4 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -66,6 +66,10 @@ from contextlib import contextmanager from opentelemetry.util import loader, types +from opentelemetry.trace.status import Status, StatusCanonicalCode + +__all__ = ["Status", "StatusCanonicalCode"] + # TODO: quarantine ParentSpan = typing.Optional[typing.Union["Span", "SpanContext"]] @@ -139,109 +143,6 @@ class SpanKind(enum.Enum): CONSUMER = 4 -class StatusCanonicalCode(enum.Enum): - """Represents the canonical set of status codes of a finished Span, following the Standard GRPC codes. See - https://github.com/open-telemetry/opentelemetry-specification/blob/2dbae9a491224f1fddfa2bb05c2a1a444c623077/specification/api-tracing.md#statuscanonicalcode. - """ - - #: Not an error; returned on success. - OK = 0 - - #: The operation was cancelled, typically by the caller. - CANCELLED = 1 - - #: Unknown error. For example, this error may be returned when 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 - - #: The 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 = 2 - - #: The deadline expired before the 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 - DEADLINE_EXCEEDED = 0 - - #: Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist, - # NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used. - NOT_FOUND = 1 - - #: The entity that a client attempted to create (e.g., file or directory) already exists. - ALREADY_EXISTS = 2 - - #: 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 can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or - # satisfies other pre-conditions. - PERMISSION_DENIED = 2 - - #: The request does not have valid authentication credentials for the operation. - UNAUTHENTICATED = 0 - - #: Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. - RESOURCE_EXHAUSTED = 1 - - #: The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. - # Service implementors can use the following guidelines to decide 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., when a client-specified test-and-set fails, indicating the client should restart 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 the files are deleted from the - # directory. - FAILED_PRECONDITION = 2 - - #: The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE. - ABORTED = 2 - - #: The 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 = 0 - - #: The operation is not implemented or is not supported/enabled in this service. - UNIMPLEMENTED = 1 - - #: Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. - INTERNAL = 2 - - #: The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations. - UNAVAILABLE = 2 - - #: Unrecoverable data loss or corruption. - DATA_LOSS = 2 - - -class Status: - """Represents the status of a finished Span - - Args: - canonical_code: Represents the canonical set of status codes of a finished Span - description: Description of the Status. - """ - - def __init__( - self, - canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, - description: typing.Optional[str] = None, - ): - self.code = canonical_code - self.desc = description - - @property - def canonical_code(self) -> StatusCanonicalCode: - """StatusCanonicalCode represents the canonical set of status codes of a finished Span, following the Standard GRPC codes - https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-tracing.md#statuscanonicalcode - """ - return self.code - - @property - def description(self) -> typing.Optional[str]: - """Status description""" - return self.desc - - @property - def is_ok(self) -> bool: - """Returns false if this Status represents an error, else returns true""" - return self.canonical_code == StatusCanonicalCode.OK - - class Span: """A span represents a single operation within a trace.""" @@ -330,7 +231,8 @@ def is_recording_events(self) -> bool: """ def set_status(self, status: Status) -> None: - """Sets the Status of the Span. If used, this will override the default Span status, which is OK. + """Sets the Status of the Span. If used, this will override the default + Span status, which is OK. """ diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py new file mode 100644 index 0000000000..8816b3ae84 --- /dev/null +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -0,0 +1,167 @@ +# Copyright 2019, OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import enum +import typing + + +class StatusCanonicalCode(enum.Enum): + """Represents the canonical set of status codes of a finished Span. + """ + + """Not an error, returned on success. """ + OK = 0 + + """The operation was cancelled, typically by the caller. """ + CANCELLED = 1 + + """Unknown error. For example, this error may be returned when 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 + + """The 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 + + """The deadline expired before the 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 + """ + DEADLINE_EXCEEDED = 4 + + """Some requested entity (e.g., file or directory) was not found. + Note to server developers: if a request is denied for an entire class of + users, such as gradual feature rollout or undocumented whitelist, NOT_FOUND + may be used. If a request is denied for some users within a class of users, + such as user-based access control, PERMISSION_DENIED must be used. + """ + NOT_FOUND = 5 + + """The entity that a client 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 can not be identified (use UNAUTHENTICATED + instead for those errors). This error code does not imply the request is + valid or the requested entity exists or satisfies other pre-conditions. + """ + PERMISSION_DENIED = 7 + + """The request does not have valid authentication credentials for the + operation. + """ + UNAUTHENTICATED = 8 + + """Some resource has been exhausted, perhaps a per-user quota, or perhaps + the entire file system is out of space. + """ + RESOURCE_EXHAUSTED = 9 + + """The operation was rejected because the system is not in a state required + for the operation's execution. For example, the directory to be deleted is + non-empty, an rmdir operation is applied to a non-directory, etc. Service + implementors can use the following guidelines to decide 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., when a client-specified test-and-set fails, + indicating the client should restart 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 the files are deleted from the directory. + """ + FAILED_PRECONDITION = 10 + + """The operation was aborted, typically due to a concurrency issue such as a + sequencer check failure or transaction abort. See the guidelines above for + deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.""" + ABORTED = 11 + + """The 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 = 12 + + """The operation is not implemented or is not supported/enabled in this + service.""" + UNIMPLEMENTED = 13 + + """Internal errors. This means that some invariants expected by the + underlying system have been broken. This error code is reserved for + serious errors. + """ + INTERNAL = 14 + + """The service is currently unavailable. This is most likely a transient + condition, which can be corrected by retrying with a backoff. + Note that it is not always safe to retry non-idempotent operations. + """ + UNAVAILABLE = 15 + + """Unrecoverable data loss or corruption.""" + DATA_LOSS = 16 + + +class Status: + """Represents the status of a finished Span + + Args: + canonical_code: Represents the canonical set of status codes of a + finished Span + description: Description of the Status. + """ + + def __init__( + self, + canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, + description: typing.Optional[str] = None, + ): + self.code = canonical_code + self.desc = description + + @property + def canonical_code(self) -> StatusCanonicalCode: + """StatusCanonicalCode represents the canonical set of status codes + of a finished Span. + """ + return self.code + + @property + def description(self) -> typing.Optional[str]: + """Status description""" + return self.desc + + @property + def is_ok(self) -> bool: + """Returns false if this Status represents an error, else + returns true""" + return self.canonical_code == StatusCanonicalCode.OK From 7fe57a12051eb26ad07a6ce8b87bd367de88a89c Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 11 Oct 2019 13:48:58 -0700 Subject: [PATCH 17/31] Fixing lint issues Updating enum values --- .../src/opentelemetry/trace/status.py | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 8816b3ae84..3a765d07d9 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -18,9 +18,9 @@ class StatusCanonicalCode(enum.Enum): """Represents the canonical set of status codes of a finished Span. + + Not an error, returned on success. """ - - """Not an error, returned on success. """ OK = 0 """The operation was cancelled, typically by the caller. """ @@ -68,15 +68,10 @@ class StatusCanonicalCode(enum.Enum): """ PERMISSION_DENIED = 7 - """The request does not have valid authentication credentials for the - operation. - """ - UNAUTHENTICATED = 8 - """Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. """ - RESOURCE_EXHAUSTED = 9 + RESOURCE_EXHAUSTED = 8 """The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is @@ -91,12 +86,12 @@ class StatusCanonicalCode(enum.Enum): non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless the files are deleted from the directory. """ - FAILED_PRECONDITION = 10 + FAILED_PRECONDITION = 9 """The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.""" - ABORTED = 11 + ABORTED = 10 """The 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 @@ -109,27 +104,31 @@ class StatusCanonicalCode(enum.Enum): through a space can easily look for an OUT_OF_RANGE error to detect when they are done. """ - OUT_OF_RANGE = 12 + OUT_OF_RANGE = 11 """The operation is not implemented or is not supported/enabled in this service.""" - UNIMPLEMENTED = 13 + UNIMPLEMENTED = 12 """Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors. """ - INTERNAL = 14 + INTERNAL = 13 """The service is currently unavailable. This is most likely a transient - condition, which can be corrected by retrying with a backoff. + condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations. """ - UNAVAILABLE = 15 + UNAVAILABLE = 14 """Unrecoverable data loss or corruption.""" - DATA_LOSS = 16 + DATA_LOSS = 15 + """The request does not have valid authentication credentials for the + operation. + """ + UNAUTHENTICATED = 16 class Status: """Represents the status of a finished Span From 57ebc24b234ef555cea7ec507edaa0cd995c3c2c Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 11 Oct 2019 14:06:38 -0700 Subject: [PATCH 18/31] Fixing formatting issues --- opentelemetry-api/src/opentelemetry/trace/status.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 3a765d07d9..2b04bce183 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -21,6 +21,7 @@ class StatusCanonicalCode(enum.Enum): Not an error, returned on success. """ + OK = 0 """The operation was cancelled, typically by the caller. """ @@ -130,6 +131,7 @@ class StatusCanonicalCode(enum.Enum): """ UNAUTHENTICATED = 16 + class Status: """Represents the status of a finished Span From 27df21be266bd67aefe4c2b4fc4b6ea592ba17d7 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 11 Oct 2019 14:30:21 -0700 Subject: [PATCH 19/31] Fixing lint issues --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 2 +- opentelemetry-api/src/opentelemetry/trace/status.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 067adbe6d4..77cfcf67bf 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -65,8 +65,8 @@ import typing from contextlib import contextmanager -from opentelemetry.util import loader, types from opentelemetry.trace.status import Status, StatusCanonicalCode +from opentelemetry.util import loader, types __all__ = ["Status", "StatusCanonicalCode"] diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 2b04bce183..c2520f97fe 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -17,11 +17,11 @@ class StatusCanonicalCode(enum.Enum): - """Represents the canonical set of status codes of a finished Span. - - Not an error, returned on success. - """ + """Represents the canonical set of status codes of a finished Span.""" + # pylint: disable=pointless-string-statement + """Not an error, returned on success. + """ OK = 0 """The operation was cancelled, typically by the caller. """ From 4ccc14241106d460bdacea27c9c96bbe3b28612d Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Fri, 11 Oct 2019 17:03:24 -0700 Subject: [PATCH 20/31] Fixing issues generating docs --- .../src/opentelemetry/trace/__init__.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 77cfcf67bf..3732b05cd7 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -68,8 +68,19 @@ from opentelemetry.trace.status import Status, StatusCanonicalCode from opentelemetry.util import loader, types -__all__ = ["Status", "StatusCanonicalCode"] - +__all__ = [ + "Status", + "StatusCanonicalCode", + "Link", + "Event", + "SpanKind", + "Span", + "SpanContext", + "TraceOptions", + "TraceState", + "DefaultSpan", + "Tracer", +] # TODO: quarantine ParentSpan = typing.Optional[typing.Union["Span", "SpanContext"]] From d08c3dbcfc756880a8664cc68f3c5605a72348b7 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 15 Oct 2019 14:43:40 -0700 Subject: [PATCH 21/31] Addressing comments Fixing docs issue --- docs/opentelemetry.trace.rst | 12 +++++++++++- docs/opentelemetry.trace.status.rst | 7 +++++++ .../src/opentelemetry/trace/__init__.py | 14 -------------- .../src/opentelemetry/trace/status.py | 7 +++---- 4 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 docs/opentelemetry.trace.status.rst diff --git a/docs/opentelemetry.trace.rst b/docs/opentelemetry.trace.rst index cec44bd817..a57b5dcbff 100644 --- a/docs/opentelemetry.trace.rst +++ b/docs/opentelemetry.trace.rst @@ -1,4 +1,14 @@ opentelemetry.trace package =========================== -.. automodule:: opentelemetry.trace +Submodules +---------- + +.. toctree:: + + opentelemetry.trace.status + +Module contents +--------------- + +.. automodule:: opentelemetry.trace \ No newline at end of file diff --git a/docs/opentelemetry.trace.status.rst b/docs/opentelemetry.trace.status.rst new file mode 100644 index 0000000000..bbc3287404 --- /dev/null +++ b/docs/opentelemetry.trace.status.rst @@ -0,0 +1,7 @@ +opentelemetry.trace.status +========================================== + +.. automodule:: opentelemetry.trace.status + :members: + :undoc-members: + :show-inheritance: diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 3732b05cd7..fd45f069af 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -68,20 +68,6 @@ from opentelemetry.trace.status import Status, StatusCanonicalCode from opentelemetry.util import loader, types -__all__ = [ - "Status", - "StatusCanonicalCode", - "Link", - "Event", - "SpanKind", - "Span", - "SpanContext", - "TraceOptions", - "TraceState", - "DefaultSpan", - "Tracer", -] - # TODO: quarantine ParentSpan = typing.Optional[typing.Union["Span", "SpanContext"]] diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index c2520f97fe..22ab29c41b 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -136,8 +136,7 @@ class Status: """Represents the status of a finished Span Args: - canonical_code: Represents the canonical set of status codes of a - finished Span + canonical_code: Represents the canonical status code. description: Description of the Status. """ @@ -150,8 +149,8 @@ def __init__( self.desc = description @property - def canonical_code(self) -> StatusCanonicalCode: - """StatusCanonicalCode represents the canonical set of status codes + def canonical_code(self) -> "StatusCanonicalCode": + """Represents the canonical status code. of a finished Span. """ return self.code From 7265b92e612e85f8b57394a38620752ed7214b27 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 15 Oct 2019 14:53:09 -0700 Subject: [PATCH 22/31] Fixing lint issue after merge --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 38348d17a1..15f61e2db9 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -227,7 +227,7 @@ def is_recording_events(self) -> bool: Returns true if this Span is active and recording information like events with the add_event operation and attributes using set_attribute. """ - + def set_status(self, status: Status) -> None: """Sets the Status of the Span. If used, this will override the default Span status, which is OK. @@ -253,6 +253,7 @@ def __exit__( self.end() return False + class TraceOptions(int): """A bitmask that represents options specific to the trace. From 98960eff1eef1f7fc69b8cadcb12b27b955a8638 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 15 Oct 2019 14:57:35 -0700 Subject: [PATCH 23/31] Lint fix --- opentelemetry-api/src/opentelemetry/trace/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/__init__.py b/opentelemetry-api/src/opentelemetry/trace/__init__.py index 15f61e2db9..fac9f55da7 100644 --- a/opentelemetry-api/src/opentelemetry/trace/__init__.py +++ b/opentelemetry-api/src/opentelemetry/trace/__init__.py @@ -66,7 +66,7 @@ import typing from contextlib import contextmanager -from opentelemetry.trace.status import Status, StatusCanonicalCode +from opentelemetry.trace.status import Status from opentelemetry.util import loader, types # TODO: quarantine From a714d204bd9f9fc92ed03ed151b8377a98307500 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 15 Oct 2019 15:04:04 -0700 Subject: [PATCH 24/31] Fix tests --- opentelemetry-sdk/tests/trace/test_trace.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index e6c091c2b1..fed7e4c9b8 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -291,13 +291,13 @@ def test_start_span(self): # default status self.assertTrue(span.status.is_ok) self.assertEqual( - span.status.canonical_code, trace_api.StatusCanonicalCode.OK + span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK ) self.assertIs(span.status.description, None) # status - new_status = trace_api.Status( - trace_api.StatusCanonicalCode.CANCELLED, "Test description" + new_status = trace_api.status.Status( + trace_api.status.StatusCanonicalCode.CANCELLED, "Test description" ) span.set_status(new_status) self.assertEqual(span.status, new_status) From ac7cf0d4ae9379d6a3588f1a0ab92eef0c3f5c42 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 15 Oct 2019 15:51:29 -0700 Subject: [PATCH 25/31] Enum docstring fixes --- .../src/opentelemetry/trace/status.py | 144 ++++++++++-------- 1 file changed, 82 insertions(+), 62 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 22ab29c41b..2df91c89d9 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -19,117 +19,137 @@ class StatusCanonicalCode(enum.Enum): """Represents the canonical set of status codes of a finished Span.""" - # pylint: disable=pointless-string-statement - """Not an error, returned on success. - """ OK = 0 + """Not an error, returned on success.""" - """The operation was cancelled, typically by the caller. """ CANCELLED = 1 + """The operation was cancelled, typically by the caller.""" - """Unknown error. For example, this error may be returned when 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 + """Unknown error. - """The 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). + For example, this error may be returned when 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. """ + INVALID_ARGUMENT = 3 + """The client specified an invalid argument. - """The deadline expired before the 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 + 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). """ + DEADLINE_EXCEEDED = 4 + """The deadline expired before the 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 + """ + + NOT_FOUND = 5 """Some requested entity (e.g., file or directory) was not found. + Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented whitelist, NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used. """ - NOT_FOUND = 5 - """The entity that a client attempted to create (e.g., file or directory) - already exists.""" ALREADY_EXISTS = 6 + """The entity that a client attempted to create (e.g., file or directory) + already exists. + """ + PERMISSION_DENIED = 7 """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 can not be identified (use UNAUTHENTICATED - instead for those errors). This error code does not imply the request is - valid or the requested entity exists or satisfies other pre-conditions. + resource (use RESOURCE_EXHAUSTED instead for those + errors).PERMISSION_DENIED must not be used if the caller can not be + identified (use UNAUTHENTICATED instead for those errors). This error code + does not imply the request is valid or the requested entity exists or + satisfies other pre-conditions. """ - PERMISSION_DENIED = 7 + RESOURCE_EXHAUSTED = 8 """Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space. """ - RESOURCE_EXHAUSTED = 8 + FAILED_PRECONDITION = 9 """The operation was rejected because the system is not in a state required - for the operation's execution. For example, the directory to be deleted is - non-empty, an rmdir operation is applied to a non-directory, etc. Service - implementors can use the following guidelines to decide 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., when a client-specified test-and-set fails, - indicating the client should restart 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 the files are deleted from the directory. + for the operation's execution. + + For example, the directory to be deleted is non-empty, an rmdir operation + is applied to a non-directory, etc. Service implementors can use the + following guidelines to decide 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., + when a client-specified test-and-set fails, indicating the client + should restart 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 the files are deleted from the directory. """ - FAILED_PRECONDITION = 9 - """The operation was aborted, typically due to a concurrency issue such as a - sequencer check failure or transaction abort. See the guidelines above for - deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.""" ABORTED = 10 + """The operation was aborted, typically due to a concurrency issue such as a + sequencer check failure or transaction abort. - """The 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. + See the guidelines above for + deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE. """ + OUT_OF_RANGE = 11 + """The 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. + """ - """The operation is not implemented or is not supported/enabled in this - service.""" UNIMPLEMENTED = 12 - - """Internal errors. This means that some invariants expected by the - underlying system have been broken. This error code is reserved for - serious errors. + """The operation is not implemented or is not supported/enabled in this + service. """ + INTERNAL = 13 + """Internal errors. - """The service is currently unavailable. This is most likely a transient - condition, which can be corrected by retrying with a backoff. - Note that it is not always safe to retry non-idempotent operations. + This means that some invariants expected by the underlying system have been + broken. This error code is reserved for serious errors. """ + UNAVAILABLE = 14 + """The service is currently unavailable. + + This is most likely a transient condition, which can be corrected by + retrying with a backoff. Note that it is not always safe to retry + non-idempotent operations. + """ - """Unrecoverable data loss or corruption.""" DATA_LOSS = 15 + """Unrecoverable data loss or corruption.""" + UNAUTHENTICATED = 16 """The request does not have valid authentication credentials for the operation. """ - UNAUTHENTICATED = 16 class Status: From 1863412aef5dc83089f709529473f9b325723e6d Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 15 Oct 2019 15:54:12 -0700 Subject: [PATCH 26/31] Docstring tweaks --- opentelemetry-api/src/opentelemetry/trace/status.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 2df91c89d9..89a568a618 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -170,9 +170,7 @@ def __init__( @property def canonical_code(self) -> "StatusCanonicalCode": - """Represents the canonical status code. - of a finished Span. - """ + """Represents the canonical status code of a finished Span.""" return self.code @property @@ -182,6 +180,5 @@ def description(self) -> typing.Optional[str]: @property def is_ok(self) -> bool: - """Returns false if this Status represents an error, else - returns true""" + """Returns false if this represents an error, true otherwise.""" return self.canonical_code == StatusCanonicalCode.OK From 27ba6a48de95191c29936f920e5760f5817f6485 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Tue, 15 Oct 2019 16:06:13 -0700 Subject: [PATCH 27/31] Fix wrap --- opentelemetry-api/src/opentelemetry/trace/status.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 89a568a618..c0b7f44a55 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -105,8 +105,8 @@ class StatusCanonicalCode(enum.Enum): """The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. - See the guidelines above for - deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE. + See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, + and UNAVAILABLE. """ OUT_OF_RANGE = 11 From d8f8c26bb188b486f6a14f601ef9cff1e9027223 Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Tue, 15 Oct 2019 16:51:41 -0700 Subject: [PATCH 28/31] Addressing comments --- opentelemetry-api/src/opentelemetry/trace/status.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 22ab29c41b..ec7a6851f6 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -145,23 +145,23 @@ def __init__( canonical_code: "StatusCanonicalCode" = StatusCanonicalCode.OK, description: typing.Optional[str] = None, ): - self.code = canonical_code - self.desc = description + self._canonical_code = canonical_code + self._description = description @property def canonical_code(self) -> "StatusCanonicalCode": """Represents the canonical status code. of a finished Span. """ - return self.code + return self._canonical_code @property def description(self) -> typing.Optional[str]: """Status description""" - return self.desc + return self._description @property def is_ok(self) -> bool: """Returns false if this Status represents an error, else returns true""" - return self.canonical_code == StatusCanonicalCode.OK + return self._canonical_code == StatusCanonicalCode.OK From c5e71eb8490c0b3a9b7b253fdbb5fdc0e1721c1c Mon Sep 17 00:00:00 2001 From: Hector Hernandez Guzman Date: Wed, 16 Oct 2019 12:01:25 -0700 Subject: [PATCH 29/31] Addressing comments --- docs/opentelemetry.trace.status.rst | 2 +- .../src/opentelemetry/trace/status.py | 8 +++---- .../src/opentelemetry/sdk/trace/__init__.py | 5 +++++ opentelemetry-sdk/tests/trace/test_trace.py | 21 +++++++++++++++++-- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/opentelemetry.trace.status.rst b/docs/opentelemetry.trace.status.rst index bbc3287404..0205446c80 100644 --- a/docs/opentelemetry.trace.status.rst +++ b/docs/opentelemetry.trace.status.rst @@ -1,5 +1,5 @@ opentelemetry.trace.status -========================================== +========================== .. automodule:: opentelemetry.trace.status :members: diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 6e99651139..4c556fc419 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -153,11 +153,11 @@ class StatusCanonicalCode(enum.Enum): class Status: - """Represents the status of a finished Span + """Represents the status of a finished Span. Args: - canonical_code: Represents the canonical status code. - description: Description of the Status. + canonical_code: The canonical status code that describes the result status of the operation. + description: An optional description of the status. """ def __init__( @@ -181,4 +181,4 @@ def description(self) -> typing.Optional[str]: @property def is_ok(self) -> bool: """Returns false if this represents an error, true otherwise.""" - return self._canonical_code == StatusCanonicalCode.OK + return self._canonical_code is StatusCanonicalCode.OK diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 0ccc9e8545..7b274f852f 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -287,6 +287,11 @@ def is_recording_events(self) -> bool: return True def set_status(self, status: trace_api.Status) -> None: + with self._lock: + has_ended = self.end_time is not None + if has_ended: + logger.warning("Calling set_status() on an ended span.") + return self.status = status diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index fed7e4c9b8..fa8547a0a5 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -290,7 +290,7 @@ def test_start_span(self): # default status self.assertTrue(span.status.is_ok) - self.assertEqual( + self.assertIs( span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK ) self.assertIs(span.status.description, None) @@ -300,7 +300,11 @@ def test_start_span(self): trace_api.status.StatusCanonicalCode.CANCELLED, "Test description" ) span.set_status(new_status) - self.assertEqual(span.status, new_status) + self.assertIs( + span.status.canonical_code, + trace_api.status.StatusCanonicalCode.CANCELLED, + ) + self.assertIs(span.status.description, "Test description") def test_span_override_start_and_end_time(self): """Span sending custom start_time and end_time values""" @@ -348,6 +352,19 @@ def test_ended_span(self): root.update_name("xxx") self.assertEqual(root.name, "root") + new_status = trace_api.status.Status( + trace_api.status.StatusCanonicalCode.CANCELLED, + "Test description", + ) + root.set_status(new_status) + # default status + self.assertTrue(root.status.is_ok) + self.assertEqual( + root.status.canonical_code, + trace_api.status.StatusCanonicalCode.OK, + ) + self.assertIs(root.status.description, None) + def span_event_start_fmt(span_processor_name, span_name): return span_processor_name + ":" + span_name + ":start" From ce3552b9478aea68cbd2602d348b62f0c9954f93 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 16 Oct 2019 14:36:03 -0700 Subject: [PATCH 30/31] Fix mangled comment wrapping --- opentelemetry-api/src/opentelemetry/trace/status.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index 4c556fc419..ace6274483 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -68,11 +68,11 @@ class StatusCanonicalCode(enum.Enum): """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 can not be - identified (use UNAUTHENTICATED instead for those errors). This error code - does not imply the request is valid or the requested entity exists or - satisfies other pre-conditions. + resource (use RESOURCE_EXHAUSTED instead for those errors). + PERMISSION_DENIED must not be used if the caller can not be identified (use + UNAUTHENTICATED instead for those errors). This error code does not imply + the request is valid or the requested entity exists or satisfies other + pre-conditions. """ RESOURCE_EXHAUSTED = 8 From 04709bdd64cbbd21d2c5f8c2732a602a84a42d5c Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Wed, 16 Oct 2019 16:17:22 -0700 Subject: [PATCH 31/31] Wrap some text --- opentelemetry-api/src/opentelemetry/trace/status.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/trace/status.py b/opentelemetry-api/src/opentelemetry/trace/status.py index ace6274483..4fc50b33e5 100644 --- a/opentelemetry-api/src/opentelemetry/trace/status.py +++ b/opentelemetry-api/src/opentelemetry/trace/status.py @@ -156,7 +156,8 @@ class Status: """Represents the status of a finished Span. Args: - canonical_code: The canonical status code that describes the result status of the operation. + canonical_code: The canonical status code that describes the result + status of the operation. description: An optional description of the status. """