Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
ocelotl committed Jul 5, 2023
2 parents 7126dda + 3f459d3 commit 1a8a0a2
Show file tree
Hide file tree
Showing 18 changed files with 318 additions and 118 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3341](https://github.com/open-telemetry/opentelemetry-python/pull/3341))
- Upgrade opentelemetry-proto to 0.20 and regen
[#3355](https://github.com/open-telemetry/opentelemetry-python/pull/3355))
- Include endpoint in Grpc transient error warning
[#3362](https://github.com/open-telemetry/opentelemetry-python/pull/3362))

## Version 1.18.0/0.39b0 (2023-05-04)

Expand Down
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,28 @@ behind this is that every PR that adds/removes public symbols fails in CI, forci
If after checking them, it is considered that they are indeed necessary, the PR will be labeled with `Skip Public API check` so that this check is not
run.

Also, we try to keep our console output as clean as possible. Most of the time this means catching expected log messages in the test cases:

``` python
from logging import WARNING

...

def test_case(self):
with self.assertLogs(level=WARNING):
some_function_that_will_log_a_warning_message()
```

Other options can be to disable logging propagation or disabling a logger altogether.

A similar approach can be followed to catch warnings:

``` python
def test_case(self):
with self.assertWarns(DeprecationWarning):
some_function_that_will_raise_a_deprecation_warning()
```

See
[`tox.ini`](https://github.com/open-telemetry/opentelemetry-python/blob/main/tox.ini)
for more detail on available tox commands.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ def __init__(
):
super().__init__()

endpoint = endpoint or environ.get(
self._endpoint = endpoint or environ.get(
OTEL_EXPORTER_OTLP_ENDPOINT, "http://localhost:4317"
)

parsed_url = urlparse(endpoint)
parsed_url = urlparse(self._endpoint)

if parsed_url.scheme == "https":
insecure = False
Expand All @@ -197,7 +197,7 @@ def __init__(
insecure = False

if parsed_url.netloc:
endpoint = parsed_url.netloc
self._endpoint = parsed_url.netloc

self._headers = headers or environ.get(OTEL_EXPORTER_OTLP_HEADERS)
if isinstance(self._headers, str):
Expand All @@ -223,14 +223,16 @@ def __init__(

if insecure:
self._client = self._stub(
insecure_channel(endpoint, compression=compression)
insecure_channel(self._endpoint, compression=compression)
)
else:
credentials = _get_credentials(
credentials, OTEL_EXPORTER_OTLP_CERTIFICATE
)
self._client = self._stub(
secure_channel(endpoint, credentials, compression=compression)
secure_channel(
self._endpoint, credentials, compression=compression
)
)

self._export_lock = threading.Lock()
Expand Down Expand Up @@ -304,18 +306,20 @@ def _export(
logger.warning(
(
"Transient error %s encountered while exporting "
"%s, retrying in %ss."
"%s to %s, retrying in %ss."
),
error.code(),
self._exporting,
self._endpoint,
delay,
)
sleep(delay)
continue
else:
logger.error(
"Failed to export %s, error code: %s",
"Failed to export %s to %s, error code: %s",
self._exporting,
self._endpoint,
error.code(),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def _exporting(self) -> str:
otlp_mock_exporter._export(Mock())
self.assertEqual(
warning.records[0].message,
"Failed to export mock, error code: None",
"Failed to export mock to localhost:4317, error code: None",
)

def code(self): # pylint: disable=function-redefined
Expand All @@ -112,7 +112,7 @@ def trailing_metadata(self):
warning.records[0].message,
(
"Transient error StatusCode.CANCELLED encountered "
"while exporting mock, retrying in 0s."
"while exporting mock to localhost:4317, retrying in 0s."
),
)

Expand Down
10 changes: 10 additions & 0 deletions opentelemetry-api/src/opentelemetry/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,13 @@ def detach(token: object) -> None:
_SUPPRESS_HTTP_INSTRUMENTATION_KEY = create_key(
"suppress_http_instrumentation"
)

__all__ = [
"Context",
"attach",
"create_key",
"detach",
"get_current",
"get_value",
"set_value",
]
5 changes: 5 additions & 0 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ def use_span(
description=f"{type(exc).__name__}: {exc}",
)
)

# This causes parent spans to set their status to ERROR and to record
# an exception as an event if a child span raises an exception even if
# such child span was started with both record_exception and
# set_status_on_exception attributes set to False.
raise

finally:
Expand Down
16 changes: 11 additions & 5 deletions opentelemetry-sdk/tests/logs/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
LoggingHandler,
LogRecord,
)
from opentelemetry.sdk._logs._internal.export import _logger
from opentelemetry.sdk._logs.export import (
BatchLogRecordProcessor,
ConsoleLogExporter,
Expand Down Expand Up @@ -167,7 +168,8 @@ def test_simple_log_record_processor_shutdown(self):
)
exporter.clear()
logger_provider.shutdown()
logger.warning("Log after shutdown")
with self.assertLogs(level=logging.WARNING):
logger.warning("Log after shutdown")
finished_logs = exporter.get_finished_logs()
self.assertEqual(len(finished_logs), 0)

Expand Down Expand Up @@ -239,7 +241,9 @@ def test_args_defaults(self):
)
def test_args_env_var_value_error(self):
exporter = InMemoryLogExporter()
_logger.disabled = True
log_record_processor = BatchLogRecordProcessor(exporter)
_logger.disabled = False
self.assertEqual(log_record_processor._exporter, exporter)
self.assertEqual(log_record_processor._max_queue_size, 2048)
self.assertEqual(log_record_processor._schedule_delay_millis, 5000)
Expand Down Expand Up @@ -315,12 +319,14 @@ def test_shutdown(self):
provider.add_log_record_processor(log_record_processor)

logger = logging.getLogger("shutdown")
logger.propagate = False
logger.addHandler(LoggingHandler(logger_provider=provider))

logger.warning("warning message: %s", "possible upcoming heatwave")
logger.error("Very high rise in temperatures across the globe")
logger.critical("Temperature hits high 420 C in Hyderabad")
with self.assertLogs(level=logging.WARNING):
logger.warning("warning message: %s", "possible upcoming heatwave")
with self.assertLogs(level=logging.WARNING):
logger.error("Very high rise in temperatures across the globe")
with self.assertLogs(level=logging.WARNING):
logger.critical("Temperature hits high 420 C in Hyderabad")

log_record_processor.shutdown()
self.assertTrue(exporter._stopped)
Expand Down
27 changes: 18 additions & 9 deletions opentelemetry-sdk/tests/logs/test_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def test_handler_default_log_level(self):
logger.debug("Debug message")
self.assertEqual(emitter_mock.emit.call_count, 0)
# Assert emit gets called for warning message
logger.warning("Warning message")
with self.assertLogs(level=logging.WARNING):
logger.warning("Warning message")
self.assertEqual(emitter_mock.emit.call_count, 1)

def test_handler_custom_log_level(self):
Expand All @@ -53,11 +54,14 @@ def test_handler_custom_log_level(self):
logger = get_logger(
level=logging.ERROR, logger_provider=emitter_provider_mock
)
logger.warning("Warning message test custom log level")
with self.assertLogs(level=logging.WARNING):
logger.warning("Warning message test custom log level")
# Make sure any log with level < ERROR is ignored
self.assertEqual(emitter_mock.emit.call_count, 0)
logger.error("Mumbai, we have a major problem")
logger.critical("No Time For Caution")
with self.assertLogs(level=logging.ERROR):
logger.error("Mumbai, we have a major problem")
with self.assertLogs(level=logging.CRITICAL):
logger.critical("No Time For Caution")
self.assertEqual(emitter_mock.emit.call_count, 2)

def test_log_record_no_span_context(self):
Expand All @@ -67,7 +71,8 @@ def test_log_record_no_span_context(self):
)
logger = get_logger(logger_provider=emitter_provider_mock)
# Assert emit gets called for warning message
logger.warning("Warning message")
with self.assertLogs(level=logging.WARNING):
logger.warning("Warning message")
args, _ = emitter_mock.emit.call_args_list[0]
log_record = args[0]

Expand All @@ -86,7 +91,8 @@ def test_log_record_user_attributes(self):
)
logger = get_logger(logger_provider=emitter_provider_mock)
# Assert emit gets called for warning message
logger.warning("Warning message", extra={"http.status_code": 200})
with self.assertLogs(level=logging.WARNING):
logger.warning("Warning message", extra={"http.status_code": 200})
args, _ = emitter_mock.emit.call_args_list[0]
log_record = args[0]

Expand All @@ -104,7 +110,8 @@ def test_log_record_exception(self):
try:
raise ZeroDivisionError("division by zero")
except ZeroDivisionError:
logger.exception("Zero Division Error")
with self.assertLogs(level=logging.ERROR):
logger.exception("Zero Division Error")
args, _ = emitter_mock.emit.call_args_list[0]
log_record = args[0]

Expand Down Expand Up @@ -137,7 +144,8 @@ def test_log_exc_info_false(self):
try:
raise ZeroDivisionError("division by zero")
except ZeroDivisionError:
logger.error("Zero Division Error", exc_info=False)
with self.assertLogs(level=logging.ERROR):
logger.error("Zero Division Error", exc_info=False)
args, _ = emitter_mock.emit.call_args_list[0]
log_record = args[0]

Expand All @@ -160,7 +168,8 @@ def test_log_record_trace_correlation(self):

tracer = trace.TracerProvider().get_tracer(__name__)
with tracer.start_as_current_span("test") as span:
logger.critical("Critical message within span")
with self.assertLogs(level=logging.CRITICAL):
logger.critical("Critical message within span")

args, _ = emitter_mock.emit.call_args_list[0]
log_record = args[0]
Expand Down
12 changes: 8 additions & 4 deletions opentelemetry-sdk/tests/logs/test_multi_log_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,18 @@ def test_log_record_processor(self):
logger.addHandler(handler)

# Test no proessor added
logger.critical("Odisha, we have another major cyclone")
with self.assertLogs(level=logging.CRITICAL):
logger.critical("Odisha, we have another major cyclone")

self.assertEqual(len(logs_list_1), 0)
self.assertEqual(len(logs_list_2), 0)

# Add one processor
provider.add_log_record_processor(processor1)
logger.warning("Brace yourself")
logger.error("Some error message")
with self.assertLogs(level=logging.WARNING):
logger.warning("Brace yourself")
with self.assertLogs(level=logging.ERROR):
logger.error("Some error message")

expected_list_1 = [
("Brace yourself", "WARNING"),
Expand All @@ -86,7 +89,8 @@ def test_log_record_processor(self):

# Add another processor
provider.add_log_record_processor(processor2)
logger.critical("Something disastrous")
with self.assertLogs(level=logging.CRITICAL):
logger.critical("Something disastrous")
expected_list_1.append(("Something disastrous", "CRITICAL"))

expected_list_2 = [("Something disastrous", "CRITICAL")]
Expand Down
7 changes: 5 additions & 2 deletions opentelemetry-sdk/tests/metrics/test_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from logging import WARNING
from unittest import TestCase
from unittest.mock import Mock

Expand Down Expand Up @@ -50,7 +51,8 @@ def test_add(self):
def test_add_non_monotonic(self):
mc = Mock()
counter = _Counter("name", Mock(), mc)
counter.add(-1.0)
with self.assertLogs(level=WARNING):
counter.add(-1.0)
mc.consume_measurement.assert_not_called()

def test_disallow_direct_counter_creation(self):
Expand Down Expand Up @@ -360,7 +362,8 @@ def test_record(self):
def test_record_non_monotonic(self):
mc = Mock()
hist = _Histogram("name", Mock(), mc)
hist.record(-1.0)
with self.assertLogs(level=WARNING):
hist.record(-1.0)
mc.consume_measurement.assert_not_called()

def test_disallow_direct_histogram_creation(self):
Expand Down
6 changes: 4 additions & 2 deletions opentelemetry-sdk/tests/metrics/test_metric_reader_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ def test_creates_view_instrument_matches(
# instrument2 matches view2, so should create a single
# ViewInstrumentMatch
MockViewInstrumentMatch.call_args_list.clear()
storage.consume_measurement(Measurement(1, instrument2))
with self.assertLogs(level=WARNING):
storage.consume_measurement(Measurement(1, instrument2))
self.assertEqual(len(MockViewInstrumentMatch.call_args_list), 1)

@patch(
Expand Down Expand Up @@ -150,7 +151,8 @@ def test_forwards_calls_to_view_instrument_match(
view_instrument_match3.consume_measurement.assert_not_called()

measurement = Measurement(1, instrument2)
storage.consume_measurement(measurement)
with self.assertLogs(level=WARNING):
storage.consume_measurement(measurement)
view_instrument_match3.consume_measurement.assert_called_once_with(
measurement
)
Expand Down
Loading

0 comments on commit 1a8a0a2

Please sign in to comment.