We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Change default port for OTLP exporter
By default the collector OTLP receiver is configured on port 55680, the current default port in the OTLP exporter is still using the old OpenCensus receiver port. This should be changed.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py`
Content:
```
1 # Copyright The OpenTelemetry Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 
16 """
17 This library allows to export tracing data to an OTLP collector.
18 
19 Usage
20 -----
21 
22 The **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the
23 `OTLP`_ collector.
24 
25 
26 .. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/
27 .. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/
28 
29 .. code:: python
30 
31     from opentelemetry import trace
32     from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter
33     from opentelemetry.sdk.resources import Resource
34     from opentelemetry.sdk.trace import TracerProvider
35     from opentelemetry.sdk.trace.export import BatchExportSpanProcessor
36 
37     # Resource can be required for some backends, e.g. Jaeger
38     # If resource wouldn't be set - traces wouldn't appears in Jaeger
39     resource = Resource(labels=labels={
40         "service.name": "service"
41     })
42 
43     trace.set_tracer_provider(TracerProvider(resource=resource)))
44     tracer = trace.get_tracer(__name__)
45 
46     otlp_exporter = OTLPSpanExporter(endpoint="localhost:55678")
47 
48     span_processor = BatchExportSpanProcessor(otlp_exporter)
49 
50     trace.get_tracer_provider().add_span_processor(span_processor)
51 
52     with tracer.start_as_current_span("foo"):
53         print("Hello world!")
54 
55 API
56 ---
57 """
58
```

Path: `exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py`
Content:
```
1 # Copyright The OpenTelemetry Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """OTLP Span Exporter"""
16 
17 import logging
18 from collections.abc import Mapping, Sequence
19 from time import sleep
20 from typing import Sequence as TypingSequence
21 
22 from backoff import expo
23 from google.rpc.error_details_pb2 import RetryInfo
24 from grpc import (
25     ChannelCredentials,
26     RpcError,
27     StatusCode,
28     insecure_channel,
29     secure_channel,
30 )
31 
32 from opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (
33     ExportTraceServiceRequest,
34 )
35 from opentelemetry.proto.collector.trace.v1.trace_service_pb2_grpc import (
36     TraceServiceStub,
37 )
38 from opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue
39 from opentelemetry.proto.resource.v1.resource_pb2 import Resource
40 from opentelemetry.proto.trace.v1.trace_pb2 import (
41     InstrumentationLibrarySpans,
42     ResourceSpans,
43 )
44 from opentelemetry.proto.trace.v1.trace_pb2 import Span as CollectorSpan
45 from opentelemetry.proto.trace.v1.trace_pb2 import Status
46 from opentelemetry.sdk.trace import Span as SDKSpan
47 from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
48 
49 logger = logging.getLogger(__name__)
50 
51 
52 def _translate_key_values(key, value):
53 
54     if isinstance(value, bool):
55         any_value = AnyValue(bool_value=value)
56 
57     elif isinstance(value, str):
58         any_value = AnyValue(string_value=value)
59 
60     elif isinstance(value, int):
61         any_value = AnyValue(int_value=value)
62 
63     elif isinstance(value, float):
64         any_value = AnyValue(double_value=value)
65 
66     elif isinstance(value, Sequence):
67         any_value = AnyValue(array_value=value)
68 
69     elif isinstance(value, Mapping):
70         any_value = AnyValue(kvlist_value=value)
71 
72     else:
73         raise Exception(
74             "Invalid type {} of value {}".format(type(value), value)
75         )
76 
77     return KeyValue(key=key, value=any_value)
78 
79 
80 # pylint: disable=no-member
81 class OTLPSpanExporter(SpanExporter):
82     """OTLP span exporter
83 
84     Args:
85         endpoint: OpenTelemetry Collector receiver endpoint
86         credentials: Credentials object for server authentication
87         metadata: Metadata to send when exporting
88     """
89 
90     def __init__(
91         self,
92         endpoint="localhost:55678",
93         credentials: ChannelCredentials = None,
94         metadata=None,
95     ):
96         super().__init__()
97 
98         self._metadata = metadata
99         self._collector_span_kwargs = None
100 
101         if credentials is None:
102             self._client = TraceServiceStub(insecure_channel(endpoint))
103         else:
104             self._client = TraceServiceStub(
105                 secure_channel(endpoint, credentials)
106             )
107 
108     def _translate_name(self, sdk_span):
109         self._collector_span_kwargs["name"] = sdk_span.name
110 
111     def _translate_start_time(self, sdk_span):
112         self._collector_span_kwargs[
113             "start_time_unix_nano"
114         ] = sdk_span.start_time
115 
116     def _translate_end_time(self, sdk_span):
117         self._collector_span_kwargs["end_time_unix_nano"] = sdk_span.end_time
118 
119     def _translate_span_id(self, sdk_span):
120         self._collector_span_kwargs[
121             "span_id"
122         ] = sdk_span.context.span_id.to_bytes(8, "big")
123 
124     def _translate_trace_id(self, sdk_span):
125         self._collector_span_kwargs[
126             "trace_id"
127         ] = sdk_span.context.trace_id.to_bytes(16, "big")
128 
129     def _translate_parent(self, sdk_span):
130         if sdk_span.parent is not None:
131             self._collector_span_kwargs[
132                 "parent_span_id"
133             ] = sdk_span.parent.span_id.to_bytes(8, "big")
134 
135     def _translate_context_trace_state(self, sdk_span):
136         if sdk_span.context.trace_state is not None:
137             self._collector_span_kwargs["trace_state"] = ",".join(
138                 [
139                     "{}={}".format(key, value)
140                     for key, value in (sdk_span.context.trace_state.items())
141                 ]
142             )
143 
144     def _translate_attributes(self, sdk_span):
145         if sdk_span.attributes:
146 
147             self._collector_span_kwargs["attributes"] = []
148 
149             for key, value in sdk_span.attributes.items():
150 
151                 try:
152                     self._collector_span_kwargs["attributes"].append(
153                         _translate_key_values(key, value)
154                     )
155                 except Exception as error:  # pylint: disable=broad-except
156                     logger.exception(error)
157 
158     def _translate_events(self, sdk_span):
159         if sdk_span.events:
160             self._collector_span_kwargs["events"] = []
161 
162             for sdk_span_event in sdk_span.events:
163 
164                 collector_span_event = CollectorSpan.Event(
165                     name=sdk_span_event.name,
166                     time_unix_nano=sdk_span_event.timestamp,
167                 )
168 
169                 for key, value in sdk_span_event.attributes.items():
170                     try:
171                         collector_span_event.attributes.append(
172                             _translate_key_values(key, value)
173                         )
174                     # pylint: disable=broad-except
175                     except Exception as error:
176                         logger.exception(error)
177 
178                 self._collector_span_kwargs["events"].append(
179                     collector_span_event
180                 )
181 
182     def _translate_links(self, sdk_span):
183         if sdk_span.links:
184             self._collector_span_kwargs["links"] = []
185 
186             for sdk_span_link in sdk_span.links:
187 
188                 collector_span_link = CollectorSpan.Link(
189                     trace_id=(
190                         sdk_span_link.context.trace_id.to_bytes(16, "big")
191                     ),
192                     span_id=(sdk_span_link.context.span_id.to_bytes(8, "big")),
193                 )
194 
195                 for key, value in sdk_span_link.attributes.items():
196                     try:
197                         collector_span_link.attributes.append(
198                             _translate_key_values(key, value)
199                         )
200                     # pylint: disable=broad-except
201                     except Exception as error:
202                         logger.exception(error)
203 
204                 self._collector_span_kwargs["links"].append(
205                     collector_span_link
206                 )
207 
208     def _translate_status(self, sdk_span):
209         if sdk_span.status is not None:
210             self._collector_span_kwargs["status"] = Status(
211                 code=sdk_span.status.canonical_code.value,
212                 message=sdk_span.status.description,
213             )
214 
215     def _translate_spans(
216         self, sdk_spans: TypingSequence[SDKSpan],
217     ) -> ExportTraceServiceRequest:
218 
219         sdk_resource_instrumentation_library_spans = {}
220 
221         for sdk_span in sdk_spans:
222 
223             if sdk_span.resource not in (
224                 sdk_resource_instrumentation_library_spans.keys()
225             ):
226                 sdk_resource_instrumentation_library_spans[
227                     sdk_span.resource
228                 ] = InstrumentationLibrarySpans()
229 
230             self._collector_span_kwargs = {}
231 
232             self._translate_name(sdk_span)
233             self._translate_start_time(sdk_span)
234             self._translate_end_time(sdk_span)
235             self._translate_span_id(sdk_span)
236             self._translate_trace_id(sdk_span)
237             self._translate_parent(sdk_span)
238             self._translate_context_trace_state(sdk_span)
239             self._translate_attributes(sdk_span)
240             self._translate_events(sdk_span)
241             self._translate_links(sdk_span)
242             self._translate_status(sdk_span)
243 
244             self._collector_span_kwargs["kind"] = getattr(
245                 CollectorSpan.SpanKind, sdk_span.kind.name
246             )
247 
248             sdk_resource_instrumentation_library_spans[
249                 sdk_span.resource
250             ].spans.append(CollectorSpan(**self._collector_span_kwargs))
251 
252         resource_spans = []
253 
254         for (
255             sdk_resource,
256             instrumentation_library_spans,
257         ) in sdk_resource_instrumentation_library_spans.items():
258 
259             collector_resource = Resource()
260 
261             for key, value in sdk_resource.labels.items():
262 
263                 try:
264                     collector_resource.attributes.append(
265                         _translate_key_values(key, value)
266                     )
267                 except Exception as error:  # pylint: disable=broad-except
268                     logger.exception(error)
269 
270             resource_spans.append(
271                 ResourceSpans(
272                     resource=collector_resource,
273                     instrumentation_library_spans=[
274                         instrumentation_library_spans
275                     ],
276                 )
277             )
278 
279         return ExportTraceServiceRequest(resource_spans=resource_spans)
280 
281     def export(self, spans: TypingSequence[SDKSpan]) -> SpanExportResult:
282         # expo returns a generator that yields delay values which grow
283         # exponentially. Once delay is greater than max_value, the yielded
284         # value will remain constant.
285         # max_value is set to 900 (900 seconds is 15 minutes) to use the same
286         # value as used in the Go implementation.
287 
288         max_value = 900
289 
290         for delay in expo(max_value=max_value):
291 
292             if delay == max_value:
293                 return SpanExportResult.FAILURE
294 
295             try:
296                 self._client.Export(
297                     request=self._translate_spans(spans),
298                     metadata=self._metadata,
299                 )
300 
301                 return SpanExportResult.SUCCESS
302 
303             except RpcError as error:
304 
305                 if error.code() in [
306                     StatusCode.CANCELLED,
307                     StatusCode.DEADLINE_EXCEEDED,
308                     StatusCode.PERMISSION_DENIED,
309                     StatusCode.UNAUTHENTICATED,
310                     StatusCode.RESOURCE_EXHAUSTED,
311                     StatusCode.ABORTED,
312                     StatusCode.OUT_OF_RANGE,
313                     StatusCode.UNAVAILABLE,
314                     StatusCode.DATA_LOSS,
315                 ]:
316 
317                     retry_info_bin = dict(error.trailing_metadata()).get(
318                         "google.rpc.retryinfo-bin"
319                     )
320                     if retry_info_bin is not None:
321                         retry_info = RetryInfo()
322                         retry_info.ParseFromString(retry_info_bin)
323                         delay = (
324                             retry_info.retry_delay.seconds
325                             + retry_info.retry_delay.nanos / 1.0e9
326                         )
327 
328                     logger.debug("Waiting %ss before retrying export of span")
329                     sleep(delay)
330                     continue
331 
332                 if error.code() == StatusCode.OK:
333                     return SpanExportResult.SUCCESS
334 
335                 return SpanExportResult.FAILURE
336 
337         return SpanExportResult.FAILURE
338 
339     def shutdown(self):
340         pass
341
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py
@@ -43,7 +43,7 @@
     trace.set_tracer_provider(TracerProvider(resource=resource)))
     tracer = trace.get_tracer(__name__)
 
-    otlp_exporter = OTLPSpanExporter(endpoint="localhost:55678")
+    otlp_exporter = OTLPSpanExporter(endpoint="localhost:55680")
 
     span_processor = BatchExportSpanProcessor(otlp_exporter)
 
diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py
--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py
+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py
@@ -89,7 +89,7 @@
 
     def __init__(
         self,
-        endpoint="localhost:55678",
+        endpoint="localhost:55680",
         credentials: ChannelCredentials = None,
         metadata=None,
     ):

{"golden_diff": "diff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py\n@@ -43,7 +43,7 @@\n     trace.set_tracer_provider(TracerProvider(resource=resource)))\n     tracer = trace.get_tracer(__name__)\n \n-    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55678\")\n+    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55680\")\n \n     span_processor = BatchExportSpanProcessor(otlp_exporter)\n \ndiff --git a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py\n--- a/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py\n+++ b/exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py\n@@ -89,7 +89,7 @@\n \n     def __init__(\n         self,\n-        endpoint=\"localhost:55678\",\n+        endpoint=\"localhost:55680\",\n         credentials: ChannelCredentials = None,\n         metadata=None,\n     ):\n", "issue": "Change default port for OTLP exporter\nBy default the collector OTLP receiver is configured on port 55680, the current default port in the OTLP exporter is still using the old OpenCensus receiver port. This should be changed.\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"\nThis library allows to export tracing data to an OTLP collector.\n\nUsage\n-----\n\nThe **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the\n`OTLP`_ collector.\n\n\n.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/\n.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/\n\n.. code:: python\n\n    from opentelemetry import trace\n    from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter\n    from opentelemetry.sdk.resources import Resource\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import BatchExportSpanProcessor\n\n    # Resource can be required for some backends, e.g. Jaeger\n    # If resource wouldn't be set - traces wouldn't appears in Jaeger\n    resource = Resource(labels=labels={\n        \"service.name\": \"service\"\n    })\n\n    trace.set_tracer_provider(TracerProvider(resource=resource)))\n    tracer = trace.get_tracer(__name__)\n\n    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55678\")\n\n    span_processor = BatchExportSpanProcessor(otlp_exporter)\n\n    trace.get_tracer_provider().add_span_processor(span_processor)\n\n    with tracer.start_as_current_span(\"foo\"):\n        print(\"Hello world!\")\n\nAPI\n---\n\"\"\"\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py"}, {"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"OTLP Span Exporter\"\"\"\n\nimport logging\nfrom collections.abc import Mapping, Sequence\nfrom time import sleep\nfrom typing import Sequence as TypingSequence\n\nfrom backoff import expo\nfrom google.rpc.error_details_pb2 import RetryInfo\nfrom grpc import (\n    ChannelCredentials,\n    RpcError,\n    StatusCode,\n    insecure_channel,\n    secure_channel,\n)\n\nfrom opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (\n    ExportTraceServiceRequest,\n)\nfrom opentelemetry.proto.collector.trace.v1.trace_service_pb2_grpc import (\n    TraceServiceStub,\n)\nfrom opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue\nfrom opentelemetry.proto.resource.v1.resource_pb2 import Resource\nfrom opentelemetry.proto.trace.v1.trace_pb2 import (\n    InstrumentationLibrarySpans,\n    ResourceSpans,\n)\nfrom opentelemetry.proto.trace.v1.trace_pb2 import Span as CollectorSpan\nfrom opentelemetry.proto.trace.v1.trace_pb2 import Status\nfrom opentelemetry.sdk.trace import Span as SDKSpan\nfrom opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n\nlogger = logging.getLogger(__name__)\n\n\ndef _translate_key_values(key, value):\n\n    if isinstance(value, bool):\n        any_value = AnyValue(bool_value=value)\n\n    elif isinstance(value, str):\n        any_value = AnyValue(string_value=value)\n\n    elif isinstance(value, int):\n        any_value = AnyValue(int_value=value)\n\n    elif isinstance(value, float):\n        any_value = AnyValue(double_value=value)\n\n    elif isinstance(value, Sequence):\n        any_value = AnyValue(array_value=value)\n\n    elif isinstance(value, Mapping):\n        any_value = AnyValue(kvlist_value=value)\n\n    else:\n        raise Exception(\n            \"Invalid type {} of value {}\".format(type(value), value)\n        )\n\n    return KeyValue(key=key, value=any_value)\n\n\n# pylint: disable=no-member\nclass OTLPSpanExporter(SpanExporter):\n    \"\"\"OTLP span exporter\n\n    Args:\n        endpoint: OpenTelemetry Collector receiver endpoint\n        credentials: Credentials object for server authentication\n        metadata: Metadata to send when exporting\n    \"\"\"\n\n    def __init__(\n        self,\n        endpoint=\"localhost:55678\",\n        credentials: ChannelCredentials = None,\n        metadata=None,\n    ):\n        super().__init__()\n\n        self._metadata = metadata\n        self._collector_span_kwargs = None\n\n        if credentials is None:\n            self._client = TraceServiceStub(insecure_channel(endpoint))\n        else:\n            self._client = TraceServiceStub(\n                secure_channel(endpoint, credentials)\n            )\n\n    def _translate_name(self, sdk_span):\n        self._collector_span_kwargs[\"name\"] = sdk_span.name\n\n    def _translate_start_time(self, sdk_span):\n        self._collector_span_kwargs[\n            \"start_time_unix_nano\"\n        ] = sdk_span.start_time\n\n    def _translate_end_time(self, sdk_span):\n        self._collector_span_kwargs[\"end_time_unix_nano\"] = sdk_span.end_time\n\n    def _translate_span_id(self, sdk_span):\n        self._collector_span_kwargs[\n            \"span_id\"\n        ] = sdk_span.context.span_id.to_bytes(8, \"big\")\n\n    def _translate_trace_id(self, sdk_span):\n        self._collector_span_kwargs[\n            \"trace_id\"\n        ] = sdk_span.context.trace_id.to_bytes(16, \"big\")\n\n    def _translate_parent(self, sdk_span):\n        if sdk_span.parent is not None:\n            self._collector_span_kwargs[\n                \"parent_span_id\"\n            ] = sdk_span.parent.span_id.to_bytes(8, \"big\")\n\n    def _translate_context_trace_state(self, sdk_span):\n        if sdk_span.context.trace_state is not None:\n            self._collector_span_kwargs[\"trace_state\"] = \",\".join(\n                [\n                    \"{}={}\".format(key, value)\n                    for key, value in (sdk_span.context.trace_state.items())\n                ]\n            )\n\n    def _translate_attributes(self, sdk_span):\n        if sdk_span.attributes:\n\n            self._collector_span_kwargs[\"attributes\"] = []\n\n            for key, value in sdk_span.attributes.items():\n\n                try:\n                    self._collector_span_kwargs[\"attributes\"].append(\n                        _translate_key_values(key, value)\n                    )\n                except Exception as error:  # pylint: disable=broad-except\n                    logger.exception(error)\n\n    def _translate_events(self, sdk_span):\n        if sdk_span.events:\n            self._collector_span_kwargs[\"events\"] = []\n\n            for sdk_span_event in sdk_span.events:\n\n                collector_span_event = CollectorSpan.Event(\n                    name=sdk_span_event.name,\n                    time_unix_nano=sdk_span_event.timestamp,\n                )\n\n                for key, value in sdk_span_event.attributes.items():\n                    try:\n                        collector_span_event.attributes.append(\n                            _translate_key_values(key, value)\n                        )\n                    # pylint: disable=broad-except\n                    except Exception as error:\n                        logger.exception(error)\n\n                self._collector_span_kwargs[\"events\"].append(\n                    collector_span_event\n                )\n\n    def _translate_links(self, sdk_span):\n        if sdk_span.links:\n            self._collector_span_kwargs[\"links\"] = []\n\n            for sdk_span_link in sdk_span.links:\n\n                collector_span_link = CollectorSpan.Link(\n                    trace_id=(\n                        sdk_span_link.context.trace_id.to_bytes(16, \"big\")\n                    ),\n                    span_id=(sdk_span_link.context.span_id.to_bytes(8, \"big\")),\n                )\n\n                for key, value in sdk_span_link.attributes.items():\n                    try:\n                        collector_span_link.attributes.append(\n                            _translate_key_values(key, value)\n                        )\n                    # pylint: disable=broad-except\n                    except Exception as error:\n                        logger.exception(error)\n\n                self._collector_span_kwargs[\"links\"].append(\n                    collector_span_link\n                )\n\n    def _translate_status(self, sdk_span):\n        if sdk_span.status is not None:\n            self._collector_span_kwargs[\"status\"] = Status(\n                code=sdk_span.status.canonical_code.value,\n                message=sdk_span.status.description,\n            )\n\n    def _translate_spans(\n        self, sdk_spans: TypingSequence[SDKSpan],\n    ) -> ExportTraceServiceRequest:\n\n        sdk_resource_instrumentation_library_spans = {}\n\n        for sdk_span in sdk_spans:\n\n            if sdk_span.resource not in (\n                sdk_resource_instrumentation_library_spans.keys()\n            ):\n                sdk_resource_instrumentation_library_spans[\n                    sdk_span.resource\n                ] = InstrumentationLibrarySpans()\n\n            self._collector_span_kwargs = {}\n\n            self._translate_name(sdk_span)\n            self._translate_start_time(sdk_span)\n            self._translate_end_time(sdk_span)\n            self._translate_span_id(sdk_span)\n            self._translate_trace_id(sdk_span)\n            self._translate_parent(sdk_span)\n            self._translate_context_trace_state(sdk_span)\n            self._translate_attributes(sdk_span)\n            self._translate_events(sdk_span)\n            self._translate_links(sdk_span)\n            self._translate_status(sdk_span)\n\n            self._collector_span_kwargs[\"kind\"] = getattr(\n                CollectorSpan.SpanKind, sdk_span.kind.name\n            )\n\n            sdk_resource_instrumentation_library_spans[\n                sdk_span.resource\n            ].spans.append(CollectorSpan(**self._collector_span_kwargs))\n\n        resource_spans = []\n\n        for (\n            sdk_resource,\n            instrumentation_library_spans,\n        ) in sdk_resource_instrumentation_library_spans.items():\n\n            collector_resource = Resource()\n\n            for key, value in sdk_resource.labels.items():\n\n                try:\n                    collector_resource.attributes.append(\n                        _translate_key_values(key, value)\n                    )\n                except Exception as error:  # pylint: disable=broad-except\n                    logger.exception(error)\n\n            resource_spans.append(\n                ResourceSpans(\n                    resource=collector_resource,\n                    instrumentation_library_spans=[\n                        instrumentation_library_spans\n                    ],\n                )\n            )\n\n        return ExportTraceServiceRequest(resource_spans=resource_spans)\n\n    def export(self, spans: TypingSequence[SDKSpan]) -> SpanExportResult:\n        # expo returns a generator that yields delay values which grow\n        # exponentially. Once delay is greater than max_value, the yielded\n        # value will remain constant.\n        # max_value is set to 900 (900 seconds is 15 minutes) to use the same\n        # value as used in the Go implementation.\n\n        max_value = 900\n\n        for delay in expo(max_value=max_value):\n\n            if delay == max_value:\n                return SpanExportResult.FAILURE\n\n            try:\n                self._client.Export(\n                    request=self._translate_spans(spans),\n                    metadata=self._metadata,\n                )\n\n                return SpanExportResult.SUCCESS\n\n            except RpcError as error:\n\n                if error.code() in [\n                    StatusCode.CANCELLED,\n                    StatusCode.DEADLINE_EXCEEDED,\n                    StatusCode.PERMISSION_DENIED,\n                    StatusCode.UNAUTHENTICATED,\n                    StatusCode.RESOURCE_EXHAUSTED,\n                    StatusCode.ABORTED,\n                    StatusCode.OUT_OF_RANGE,\n                    StatusCode.UNAVAILABLE,\n                    StatusCode.DATA_LOSS,\n                ]:\n\n                    retry_info_bin = dict(error.trailing_metadata()).get(\n                        \"google.rpc.retryinfo-bin\"\n                    )\n                    if retry_info_bin is not None:\n                        retry_info = RetryInfo()\n                        retry_info.ParseFromString(retry_info_bin)\n                        delay = (\n                            retry_info.retry_delay.seconds\n                            + retry_info.retry_delay.nanos / 1.0e9\n                        )\n\n                    logger.debug(\"Waiting %ss before retrying export of span\")\n                    sleep(delay)\n                    continue\n\n                if error.code() == StatusCode.OK:\n                    return SpanExportResult.SUCCESS\n\n                return SpanExportResult.FAILURE\n\n        return SpanExportResult.FAILURE\n\n    def shutdown(self):\n        pass\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\n\"\"\"\nThis library allows to export tracing data to an OTLP collector.\n\nUsage\n-----\n\nThe **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the\n`OTLP`_ collector.\n\n\n.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/\n.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/\n\n.. code:: python\n\n    from opentelemetry import trace\n    from opentelemetry.exporter.otlp.trace_exporter import OTLPSpanExporter\n    from opentelemetry.sdk.resources import Resource\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import BatchExportSpanProcessor\n\n    # Resource can be required for some backends, e.g. Jaeger\n    # If resource wouldn't be set - traces wouldn't appears in Jaeger\n    resource = Resource(labels=labels={\n        \"service.name\": \"service\"\n    })\n\n    trace.set_tracer_provider(TracerProvider(resource=resource)))\n    tracer = trace.get_tracer(__name__)\n\n    otlp_exporter = OTLPSpanExporter(endpoint=\"localhost:55680\")\n\n    span_processor = BatchExportSpanProcessor(otlp_exporter)\n\n    trace.get_tracer_provider().add_span_processor(span_processor)\n\n    with tracer.start_as_current_span(\"foo\"):\n        print(\"Hello world!\")\n\nAPI\n---\n\"\"\"\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/__init__.py"}, {"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"OTLP Span Exporter\"\"\"\n\nimport logging\nfrom collections.abc import Mapping, Sequence\nfrom time import sleep\nfrom typing import Sequence as TypingSequence\n\nfrom backoff import expo\nfrom google.rpc.error_details_pb2 import RetryInfo\nfrom grpc import (\n    ChannelCredentials,\n    RpcError,\n    StatusCode,\n    insecure_channel,\n    secure_channel,\n)\n\nfrom opentelemetry.proto.collector.trace.v1.trace_service_pb2 import (\n    ExportTraceServiceRequest,\n)\nfrom opentelemetry.proto.collector.trace.v1.trace_service_pb2_grpc import (\n    TraceServiceStub,\n)\nfrom opentelemetry.proto.common.v1.common_pb2 import AnyValue, KeyValue\nfrom opentelemetry.proto.resource.v1.resource_pb2 import Resource\nfrom opentelemetry.proto.trace.v1.trace_pb2 import (\n    InstrumentationLibrarySpans,\n    ResourceSpans,\n)\nfrom opentelemetry.proto.trace.v1.trace_pb2 import Span as CollectorSpan\nfrom opentelemetry.proto.trace.v1.trace_pb2 import Status\nfrom opentelemetry.sdk.trace import Span as SDKSpan\nfrom opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult\n\nlogger = logging.getLogger(__name__)\n\n\ndef _translate_key_values(key, value):\n\n    if isinstance(value, bool):\n        any_value = AnyValue(bool_value=value)\n\n    elif isinstance(value, str):\n        any_value = AnyValue(string_value=value)\n\n    elif isinstance(value, int):\n        any_value = AnyValue(int_value=value)\n\n    elif isinstance(value, float):\n        any_value = AnyValue(double_value=value)\n\n    elif isinstance(value, Sequence):\n        any_value = AnyValue(array_value=value)\n\n    elif isinstance(value, Mapping):\n        any_value = AnyValue(kvlist_value=value)\n\n    else:\n        raise Exception(\n            \"Invalid type {} of value {}\".format(type(value), value)\n        )\n\n    return KeyValue(key=key, value=any_value)\n\n\n# pylint: disable=no-member\nclass OTLPSpanExporter(SpanExporter):\n    \"\"\"OTLP span exporter\n\n    Args:\n        endpoint: OpenTelemetry Collector receiver endpoint\n        credentials: Credentials object for server authentication\n        metadata: Metadata to send when exporting\n    \"\"\"\n\n    def __init__(\n        self,\n        endpoint=\"localhost:55680\",\n        credentials: ChannelCredentials = None,\n        metadata=None,\n    ):\n        super().__init__()\n\n        self._metadata = metadata\n        self._collector_span_kwargs = None\n\n        if credentials is None:\n            self._client = TraceServiceStub(insecure_channel(endpoint))\n        else:\n            self._client = TraceServiceStub(\n                secure_channel(endpoint, credentials)\n            )\n\n    def _translate_name(self, sdk_span):\n        self._collector_span_kwargs[\"name\"] = sdk_span.name\n\n    def _translate_start_time(self, sdk_span):\n        self._collector_span_kwargs[\n            \"start_time_unix_nano\"\n        ] = sdk_span.start_time\n\n    def _translate_end_time(self, sdk_span):\n        self._collector_span_kwargs[\"end_time_unix_nano\"] = sdk_span.end_time\n\n    def _translate_span_id(self, sdk_span):\n        self._collector_span_kwargs[\n            \"span_id\"\n        ] = sdk_span.context.span_id.to_bytes(8, \"big\")\n\n    def _translate_trace_id(self, sdk_span):\n        self._collector_span_kwargs[\n            \"trace_id\"\n        ] = sdk_span.context.trace_id.to_bytes(16, \"big\")\n\n    def _translate_parent(self, sdk_span):\n        if sdk_span.parent is not None:\n            self._collector_span_kwargs[\n                \"parent_span_id\"\n            ] = sdk_span.parent.span_id.to_bytes(8, \"big\")\n\n    def _translate_context_trace_state(self, sdk_span):\n        if sdk_span.context.trace_state is not None:\n            self._collector_span_kwargs[\"trace_state\"] = \",\".join(\n                [\n                    \"{}={}\".format(key, value)\n                    for key, value in (sdk_span.context.trace_state.items())\n                ]\n            )\n\n    def _translate_attributes(self, sdk_span):\n        if sdk_span.attributes:\n\n            self._collector_span_kwargs[\"attributes\"] = []\n\n            for key, value in sdk_span.attributes.items():\n\n                try:\n                    self._collector_span_kwargs[\"attributes\"].append(\n                        _translate_key_values(key, value)\n                    )\n                except Exception as error:  # pylint: disable=broad-except\n                    logger.exception(error)\n\n    def _translate_events(self, sdk_span):\n        if sdk_span.events:\n            self._collector_span_kwargs[\"events\"] = []\n\n            for sdk_span_event in sdk_span.events:\n\n                collector_span_event = CollectorSpan.Event(\n                    name=sdk_span_event.name,\n                    time_unix_nano=sdk_span_event.timestamp,\n                )\n\n                for key, value in sdk_span_event.attributes.items():\n                    try:\n                        collector_span_event.attributes.append(\n                            _translate_key_values(key, value)\n                        )\n                    # pylint: disable=broad-except\n                    except Exception as error:\n                        logger.exception(error)\n\n                self._collector_span_kwargs[\"events\"].append(\n                    collector_span_event\n                )\n\n    def _translate_links(self, sdk_span):\n        if sdk_span.links:\n            self._collector_span_kwargs[\"links\"] = []\n\n            for sdk_span_link in sdk_span.links:\n\n                collector_span_link = CollectorSpan.Link(\n                    trace_id=(\n                        sdk_span_link.context.trace_id.to_bytes(16, \"big\")\n                    ),\n                    span_id=(sdk_span_link.context.span_id.to_bytes(8, \"big\")),\n                )\n\n                for key, value in sdk_span_link.attributes.items():\n                    try:\n                        collector_span_link.attributes.append(\n                            _translate_key_values(key, value)\n                        )\n                    # pylint: disable=broad-except\n                    except Exception as error:\n                        logger.exception(error)\n\n                self._collector_span_kwargs[\"links\"].append(\n                    collector_span_link\n                )\n\n    def _translate_status(self, sdk_span):\n        if sdk_span.status is not None:\n            self._collector_span_kwargs[\"status\"] = Status(\n                code=sdk_span.status.canonical_code.value,\n                message=sdk_span.status.description,\n            )\n\n    def _translate_spans(\n        self, sdk_spans: TypingSequence[SDKSpan],\n    ) -> ExportTraceServiceRequest:\n\n        sdk_resource_instrumentation_library_spans = {}\n\n        for sdk_span in sdk_spans:\n\n            if sdk_span.resource not in (\n                sdk_resource_instrumentation_library_spans.keys()\n            ):\n                sdk_resource_instrumentation_library_spans[\n                    sdk_span.resource\n                ] = InstrumentationLibrarySpans()\n\n            self._collector_span_kwargs = {}\n\n            self._translate_name(sdk_span)\n            self._translate_start_time(sdk_span)\n            self._translate_end_time(sdk_span)\n            self._translate_span_id(sdk_span)\n            self._translate_trace_id(sdk_span)\n            self._translate_parent(sdk_span)\n            self._translate_context_trace_state(sdk_span)\n            self._translate_attributes(sdk_span)\n            self._translate_events(sdk_span)\n            self._translate_links(sdk_span)\n            self._translate_status(sdk_span)\n\n            self._collector_span_kwargs[\"kind\"] = getattr(\n                CollectorSpan.SpanKind, sdk_span.kind.name\n            )\n\n            sdk_resource_instrumentation_library_spans[\n                sdk_span.resource\n            ].spans.append(CollectorSpan(**self._collector_span_kwargs))\n\n        resource_spans = []\n\n        for (\n            sdk_resource,\n            instrumentation_library_spans,\n        ) in sdk_resource_instrumentation_library_spans.items():\n\n            collector_resource = Resource()\n\n            for key, value in sdk_resource.labels.items():\n\n                try:\n                    collector_resource.attributes.append(\n                        _translate_key_values(key, value)\n                    )\n                except Exception as error:  # pylint: disable=broad-except\n                    logger.exception(error)\n\n            resource_spans.append(\n                ResourceSpans(\n                    resource=collector_resource,\n                    instrumentation_library_spans=[\n                        instrumentation_library_spans\n                    ],\n                )\n            )\n\n        return ExportTraceServiceRequest(resource_spans=resource_spans)\n\n    def export(self, spans: TypingSequence[SDKSpan]) -> SpanExportResult:\n        # expo returns a generator that yields delay values which grow\n        # exponentially. Once delay is greater than max_value, the yielded\n        # value will remain constant.\n        # max_value is set to 900 (900 seconds is 15 minutes) to use the same\n        # value as used in the Go implementation.\n\n        max_value = 900\n\n        for delay in expo(max_value=max_value):\n\n            if delay == max_value:\n                return SpanExportResult.FAILURE\n\n            try:\n                self._client.Export(\n                    request=self._translate_spans(spans),\n                    metadata=self._metadata,\n                )\n\n                return SpanExportResult.SUCCESS\n\n            except RpcError as error:\n\n                if error.code() in [\n                    StatusCode.CANCELLED,\n                    StatusCode.DEADLINE_EXCEEDED,\n                    StatusCode.PERMISSION_DENIED,\n                    StatusCode.UNAUTHENTICATED,\n                    StatusCode.RESOURCE_EXHAUSTED,\n                    StatusCode.ABORTED,\n                    StatusCode.OUT_OF_RANGE,\n                    StatusCode.UNAVAILABLE,\n                    StatusCode.DATA_LOSS,\n                ]:\n\n                    retry_info_bin = dict(error.trailing_metadata()).get(\n                        \"google.rpc.retryinfo-bin\"\n                    )\n                    if retry_info_bin is not None:\n                        retry_info = RetryInfo()\n                        retry_info.ParseFromString(retry_info_bin)\n                        delay = (\n                            retry_info.retry_delay.seconds\n                            + retry_info.retry_delay.nanos / 1.0e9\n                        )\n\n                    logger.debug(\"Waiting %ss before retrying export of span\")\n                    sleep(delay)\n                    continue\n\n                if error.code() == StatusCode.OK:\n                    return SpanExportResult.SUCCESS\n\n                return SpanExportResult.FAILURE\n\n        return SpanExportResult.FAILURE\n\n    def shutdown(self):\n        pass\n", "path": "exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/trace_exporter/__init__.py"}]}