We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Consider renaming Resource.create_empty() to Resource.get_empty()
Specially given the fact a cached instance is returned, i.e. no actual creation happens.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opentelemetry-sdk/src/opentelemetry/sdk/resources/__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 This package implements `OpenTelemetry Resources
17 <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#resource-sdk>`_:
18 
19     *A Resource is an immutable representation of the entity producing
20     telemetry. For example, a process producing telemetry that is running in
21     a container on Kubernetes has a Pod name, it is in a namespace and
22     possibly is part of a Deployment which also has a name. All three of
23     these attributes can be included in the Resource.*
24 
25 Resource objects are created with `Resource.create`, which accepts attributes
26 (key-values). Resource attributes can also be passed at process invocation in
27 the :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable. You should
28 register your resource with the  `opentelemetry.sdk.trace.TracerProvider` by
29 passing them into their constructors. The `Resource` passed to a provider is
30 available to the exporter, which can send on this information as it sees fit.
31 
32 .. code-block:: python
33 
34     trace.set_tracer_provider(
35         TracerProvider(
36             resource=Resource.create({
37                 "service.name": "shoppingcart",
38                 "service.instance.id": "instance-12",
39             }),
40         ),
41     )
42     print(trace.get_tracer_provider().resource.attributes)
43 
44     {'telemetry.sdk.language': 'python',
45     'telemetry.sdk.name': 'opentelemetry',
46     'telemetry.sdk.version': '0.13.dev0',
47     'service.name': 'shoppingcart',
48     'service.instance.id': 'instance-12'}
49 
50 Note that the OpenTelemetry project documents certain `"standard attributes"
51 <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md>`_
52 that have prescribed semantic meanings, for example ``service.name`` in the
53 above example.
54 
55 .. envvar:: OTEL_RESOURCE_ATTRIBUTES
56 
57 The :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable allows resource
58 attributes to be passed to the SDK at process invocation. The attributes from
59 :envvar:`OTEL_RESOURCE_ATTRIBUTES` are merged with those passed to
60 `Resource.create`, meaning :envvar:`OTEL_RESOURCE_ATTRIBUTES` takes *lower*
61 priority. Attributes should be in the format ``key1=value1,key2=value2``.
62 Additional details are available `in the specification
63 <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable>`_.
64 
65 .. code-block:: console
66 
67     $ OTEL_RESOURCE_ATTRIBUTES="service.name=shoppingcard,will_be_overridden=foo" python - <<EOF
68     import pprint
69     from opentelemetry.sdk.resources import Resource
70     pprint.pprint(Resource.create({"will_be_overridden": "bar"}).attributes)
71     EOF
72     {'service.name': 'shoppingcard',
73     'telemetry.sdk.language': 'python',
74     'telemetry.sdk.name': 'opentelemetry',
75     'telemetry.sdk.version': '0.13.dev0',
76     'will_be_overridden': 'bar'}
77  """
78 
79 import abc
80 import concurrent.futures
81 import logging
82 import os
83 import typing
84 from json import dumps
85 
86 import pkg_resources
87 
88 from opentelemetry.sdk.environment_variables import OTEL_RESOURCE_ATTRIBUTES
89 
90 LabelValue = typing.Union[str, bool, int, float]
91 Attributes = typing.Dict[str, LabelValue]
92 logger = logging.getLogger(__name__)
93 
94 
95 CLOUD_PROVIDER = "cloud.provider"
96 CLOUD_ACCOUNT_ID = "cloud.account.id"
97 CLOUD_REGION = "cloud.region"
98 CLOUD_ZONE = "cloud.zone"
99 CONTAINER_NAME = "container.name"
100 CONTAINER_ID = "container.id"
101 CONTAINER_IMAGE_NAME = "container.image.name"
102 CONTAINER_IMAGE_TAG = "container.image.tag"
103 DEPLOYMENT_ENVIRONMENT = "deployment.environment"
104 FAAS_NAME = "faas.name"
105 FAAS_ID = "faas.id"
106 FAAS_VERSION = "faas.version"
107 FAAS_INSTANCE = "faas.instance"
108 HOST_NAME = "host.name"
109 HOST_TYPE = "host.type"
110 HOST_IMAGE_NAME = "host.image.name"
111 HOST_IMAGE_ID = "host.image.id"
112 HOST_IMAGE_VERSION = "host.image.version"
113 KUBERNETES_CLUSTER_NAME = "k8s.cluster.name"
114 KUBERNETES_NAMESPACE_NAME = "k8s.namespace.name"
115 KUBERNETES_POD_UID = "k8s.pod.uid"
116 KUBERNETES_POD_NAME = "k8s.pod.name"
117 KUBERNETES_CONTAINER_NAME = "k8s.container.name"
118 KUBERNETES_REPLICA_SET_UID = "k8s.replicaset.uid"
119 KUBERNETES_REPLICA_SET_NAME = "k8s.replicaset.name"
120 KUBERNETES_DEPLOYMENT_UID = "k8s.deployment.uid"
121 KUBERNETES_DEPLOYMENT_NAME = "k8s.deployment.name"
122 KUBERNETES_STATEFUL_SET_UID = "k8s.statefulset.uid"
123 KUBERNETES_STATEFUL_SET_NAME = "k8s.statefulset.name"
124 KUBERNETES_DAEMON_SET_UID = "k8s.daemonset.uid"
125 KUBERNETES_DAEMON_SET_NAME = "k8s.daemonset.name"
126 KUBERNETES_JOB_UID = "k8s.job.uid"
127 KUBERNETES_JOB_NAME = "k8s.job.name"
128 KUBERNETES_CRON_JOB_UID = "k8s.cronjob.uid"
129 KUBERNETES_CRON_JOB_NAME = "k8s.cronjob.name"
130 OS_TYPE = "os.type"
131 OS_DESCRIPTION = "os.description"
132 PROCESS_PID = "process.pid"
133 PROCESS_EXECUTABLE_NAME = "process.executable.name"
134 PROCESS_EXECUTABLE_PATH = "process.executable.path"
135 PROCESS_COMMAND = "process.command"
136 PROCESS_COMMAND_LINE = "process.command_line"
137 PROCESS_COMMAND_ARGS = "process.command_args"
138 PROCESS_OWNER = "process.owner"
139 PROCESS_RUNTIME_NAME = "process.runtime.name"
140 PROCESS_RUNTIME_VERSION = "process.runtime.version"
141 PROCESS_RUNTIME_DESCRIPTION = "process.runtime.description"
142 SERVICE_NAME = "service.name"
143 SERVICE_NAMESPACE = "service.namespace"
144 SERVICE_INSTANCE_ID = "service.instance.id"
145 SERVICE_VERSION = "service.version"
146 TELEMETRY_SDK_NAME = "telemetry.sdk.name"
147 TELEMETRY_SDK_VERSION = "telemetry.sdk.version"
148 TELEMETRY_AUTO_VERSION = "telemetry.auto.version"
149 TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language"
150 
151 
152 OPENTELEMETRY_SDK_VERSION = pkg_resources.get_distribution(
153     "opentelemetry-sdk"
154 ).version
155 
156 
157 class Resource:
158     """A Resource is an immutable representation of the entity producing telemetry as Attributes."""
159 
160     def __init__(self, attributes: Attributes):
161         self._attributes = attributes.copy()
162 
163     @staticmethod
164     def create(attributes: typing.Optional[Attributes] = None) -> "Resource":
165         """Creates a new `Resource` from attributes.
166 
167         Args:
168             attributes: Optional zero or more key-value pairs.
169 
170         Returns:
171             The newly-created Resource.
172         """
173         if not attributes:
174             attributes = {}
175         resource = _DEFAULT_RESOURCE.merge(
176             OTELResourceDetector().detect()
177         ).merge(Resource(attributes))
178         if not resource.attributes.get(SERVICE_NAME, None):
179             default_service_name = "unknown_service"
180             process_executable_name = resource.attributes.get(
181                 PROCESS_EXECUTABLE_NAME, None
182             )
183             if process_executable_name:
184                 default_service_name += ":" + process_executable_name
185             resource = resource.merge(
186                 Resource({SERVICE_NAME: default_service_name})
187             )
188         return resource
189 
190     @staticmethod
191     def create_empty() -> "Resource":
192         return _EMPTY_RESOURCE
193 
194     @property
195     def attributes(self) -> Attributes:
196         return self._attributes.copy()
197 
198     def merge(self, other: "Resource") -> "Resource":
199         """Merges this resource and an updating resource into a new `Resource`.
200 
201         If a key exists on both the old and updating resource, the value of the
202         updating resource will override the old resource value.
203 
204         Args:
205             other: The other resource to be merged.
206 
207         Returns:
208             The newly-created Resource.
209         """
210         merged_attributes = self.attributes
211         merged_attributes.update(other.attributes)
212         return Resource(merged_attributes)
213 
214     def __eq__(self, other: object) -> bool:
215         if not isinstance(other, Resource):
216             return False
217         return self._attributes == other._attributes
218 
219     def __hash__(self):
220         return hash(dumps(self._attributes, sort_keys=True))
221 
222 
223 _EMPTY_RESOURCE = Resource({})
224 _DEFAULT_RESOURCE = Resource(
225     {
226         TELEMETRY_SDK_LANGUAGE: "python",
227         TELEMETRY_SDK_NAME: "opentelemetry",
228         TELEMETRY_SDK_VERSION: OPENTELEMETRY_SDK_VERSION,
229     }
230 )
231 
232 
233 class ResourceDetector(abc.ABC):
234     def __init__(self, raise_on_error=False):
235         self.raise_on_error = raise_on_error
236 
237     @abc.abstractmethod
238     def detect(self) -> "Resource":
239         raise NotImplementedError()
240 
241 
242 class OTELResourceDetector(ResourceDetector):
243     # pylint: disable=no-self-use
244     def detect(self) -> "Resource":
245         env_resources_items = os.environ.get(OTEL_RESOURCE_ATTRIBUTES)
246         env_resource_map = {}
247         if env_resources_items:
248             env_resource_map = {
249                 key.strip(): value.strip()
250                 for key, value in (
251                     item.split("=") for item in env_resources_items.split(",")
252                 )
253             }
254         return Resource(env_resource_map)
255 
256 
257 def get_aggregated_resources(
258     detectors: typing.List["ResourceDetector"],
259     initial_resource: typing.Optional[Resource] = None,
260     timeout=5,
261 ) -> "Resource":
262     """Retrieves resources from detectors in the order that they were passed
263 
264     :param detectors: List of resources in order of priority
265     :param initial_resource: Static resource. This has highest priority
266     :param timeout: Number of seconds to wait for each detector to return
267     :return:
268     """
269     final_resource = initial_resource or _EMPTY_RESOURCE
270     detectors = [OTELResourceDetector()] + detectors
271 
272     with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
273         futures = [executor.submit(detector.detect) for detector in detectors]
274         for detector_ind, future in enumerate(futures):
275             detector = detectors[detector_ind]
276             try:
277                 detected_resources = future.result(timeout=timeout)
278             # pylint: disable=broad-except
279             except Exception as ex:
280                 if detector.raise_on_error:
281                     raise ex
282                 logger.warning(
283                     "Exception %s in detector %s, ignoring", ex, detector
284                 )
285                 detected_resources = _EMPTY_RESOURCE
286             finally:
287                 final_resource = final_resource.merge(detected_resources)
288     return final_resource
289
```
--- 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/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py
--- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py
+++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py
@@ -188,7 +188,7 @@
         return resource
 
     @staticmethod
-    def create_empty() -> "Resource":
+    def get_empty() -> "Resource":
         return _EMPTY_RESOURCE
 
     @property

{"golden_diff": "diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py\n--- a/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py\n+++ b/opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py\n@@ -188,7 +188,7 @@\n         return resource\n \n     @staticmethod\n-    def create_empty() -> \"Resource\":\n+    def get_empty() -> \"Resource\":\n         return _EMPTY_RESOURCE\n \n     @property\n", "issue": "Consider renaming Resource.create_empty() to Resource.get_empty()\nSpecially given the fact a cached instance is returned, i.e. no actual creation happens.\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\"\"\"\nThis package implements `OpenTelemetry Resources\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#resource-sdk>`_:\n\n    *A Resource is an immutable representation of the entity producing\n    telemetry. For example, a process producing telemetry that is running in\n    a container on Kubernetes has a Pod name, it is in a namespace and\n    possibly is part of a Deployment which also has a name. All three of\n    these attributes can be included in the Resource.*\n\nResource objects are created with `Resource.create`, which accepts attributes\n(key-values). Resource attributes can also be passed at process invocation in\nthe :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable. You should\nregister your resource with the  `opentelemetry.sdk.trace.TracerProvider` by\npassing them into their constructors. The `Resource` passed to a provider is\navailable to the exporter, which can send on this information as it sees fit.\n\n.. code-block:: python\n\n    trace.set_tracer_provider(\n        TracerProvider(\n            resource=Resource.create({\n                \"service.name\": \"shoppingcart\",\n                \"service.instance.id\": \"instance-12\",\n            }),\n        ),\n    )\n    print(trace.get_tracer_provider().resource.attributes)\n\n    {'telemetry.sdk.language': 'python',\n    'telemetry.sdk.name': 'opentelemetry',\n    'telemetry.sdk.version': '0.13.dev0',\n    'service.name': 'shoppingcart',\n    'service.instance.id': 'instance-12'}\n\nNote that the OpenTelemetry project documents certain `\"standard attributes\"\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md>`_\nthat have prescribed semantic meanings, for example ``service.name`` in the\nabove example.\n\n.. envvar:: OTEL_RESOURCE_ATTRIBUTES\n\nThe :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable allows resource\nattributes to be passed to the SDK at process invocation. The attributes from\n:envvar:`OTEL_RESOURCE_ATTRIBUTES` are merged with those passed to\n`Resource.create`, meaning :envvar:`OTEL_RESOURCE_ATTRIBUTES` takes *lower*\npriority. Attributes should be in the format ``key1=value1,key2=value2``.\nAdditional details are available `in the specification\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable>`_.\n\n.. code-block:: console\n\n    $ OTEL_RESOURCE_ATTRIBUTES=\"service.name=shoppingcard,will_be_overridden=foo\" python - <<EOF\n    import pprint\n    from opentelemetry.sdk.resources import Resource\n    pprint.pprint(Resource.create({\"will_be_overridden\": \"bar\"}).attributes)\n    EOF\n    {'service.name': 'shoppingcard',\n    'telemetry.sdk.language': 'python',\n    'telemetry.sdk.name': 'opentelemetry',\n    'telemetry.sdk.version': '0.13.dev0',\n    'will_be_overridden': 'bar'}\n \"\"\"\n\nimport abc\nimport concurrent.futures\nimport logging\nimport os\nimport typing\nfrom json import dumps\n\nimport pkg_resources\n\nfrom opentelemetry.sdk.environment_variables import OTEL_RESOURCE_ATTRIBUTES\n\nLabelValue = typing.Union[str, bool, int, float]\nAttributes = typing.Dict[str, LabelValue]\nlogger = logging.getLogger(__name__)\n\n\nCLOUD_PROVIDER = \"cloud.provider\"\nCLOUD_ACCOUNT_ID = \"cloud.account.id\"\nCLOUD_REGION = \"cloud.region\"\nCLOUD_ZONE = \"cloud.zone\"\nCONTAINER_NAME = \"container.name\"\nCONTAINER_ID = \"container.id\"\nCONTAINER_IMAGE_NAME = \"container.image.name\"\nCONTAINER_IMAGE_TAG = \"container.image.tag\"\nDEPLOYMENT_ENVIRONMENT = \"deployment.environment\"\nFAAS_NAME = \"faas.name\"\nFAAS_ID = \"faas.id\"\nFAAS_VERSION = \"faas.version\"\nFAAS_INSTANCE = \"faas.instance\"\nHOST_NAME = \"host.name\"\nHOST_TYPE = \"host.type\"\nHOST_IMAGE_NAME = \"host.image.name\"\nHOST_IMAGE_ID = \"host.image.id\"\nHOST_IMAGE_VERSION = \"host.image.version\"\nKUBERNETES_CLUSTER_NAME = \"k8s.cluster.name\"\nKUBERNETES_NAMESPACE_NAME = \"k8s.namespace.name\"\nKUBERNETES_POD_UID = \"k8s.pod.uid\"\nKUBERNETES_POD_NAME = \"k8s.pod.name\"\nKUBERNETES_CONTAINER_NAME = \"k8s.container.name\"\nKUBERNETES_REPLICA_SET_UID = \"k8s.replicaset.uid\"\nKUBERNETES_REPLICA_SET_NAME = \"k8s.replicaset.name\"\nKUBERNETES_DEPLOYMENT_UID = \"k8s.deployment.uid\"\nKUBERNETES_DEPLOYMENT_NAME = \"k8s.deployment.name\"\nKUBERNETES_STATEFUL_SET_UID = \"k8s.statefulset.uid\"\nKUBERNETES_STATEFUL_SET_NAME = \"k8s.statefulset.name\"\nKUBERNETES_DAEMON_SET_UID = \"k8s.daemonset.uid\"\nKUBERNETES_DAEMON_SET_NAME = \"k8s.daemonset.name\"\nKUBERNETES_JOB_UID = \"k8s.job.uid\"\nKUBERNETES_JOB_NAME = \"k8s.job.name\"\nKUBERNETES_CRON_JOB_UID = \"k8s.cronjob.uid\"\nKUBERNETES_CRON_JOB_NAME = \"k8s.cronjob.name\"\nOS_TYPE = \"os.type\"\nOS_DESCRIPTION = \"os.description\"\nPROCESS_PID = \"process.pid\"\nPROCESS_EXECUTABLE_NAME = \"process.executable.name\"\nPROCESS_EXECUTABLE_PATH = \"process.executable.path\"\nPROCESS_COMMAND = \"process.command\"\nPROCESS_COMMAND_LINE = \"process.command_line\"\nPROCESS_COMMAND_ARGS = \"process.command_args\"\nPROCESS_OWNER = \"process.owner\"\nPROCESS_RUNTIME_NAME = \"process.runtime.name\"\nPROCESS_RUNTIME_VERSION = \"process.runtime.version\"\nPROCESS_RUNTIME_DESCRIPTION = \"process.runtime.description\"\nSERVICE_NAME = \"service.name\"\nSERVICE_NAMESPACE = \"service.namespace\"\nSERVICE_INSTANCE_ID = \"service.instance.id\"\nSERVICE_VERSION = \"service.version\"\nTELEMETRY_SDK_NAME = \"telemetry.sdk.name\"\nTELEMETRY_SDK_VERSION = \"telemetry.sdk.version\"\nTELEMETRY_AUTO_VERSION = \"telemetry.auto.version\"\nTELEMETRY_SDK_LANGUAGE = \"telemetry.sdk.language\"\n\n\nOPENTELEMETRY_SDK_VERSION = pkg_resources.get_distribution(\n    \"opentelemetry-sdk\"\n).version\n\n\nclass Resource:\n    \"\"\"A Resource is an immutable representation of the entity producing telemetry as Attributes.\"\"\"\n\n    def __init__(self, attributes: Attributes):\n        self._attributes = attributes.copy()\n\n    @staticmethod\n    def create(attributes: typing.Optional[Attributes] = None) -> \"Resource\":\n        \"\"\"Creates a new `Resource` from attributes.\n\n        Args:\n            attributes: Optional zero or more key-value pairs.\n\n        Returns:\n            The newly-created Resource.\n        \"\"\"\n        if not attributes:\n            attributes = {}\n        resource = _DEFAULT_RESOURCE.merge(\n            OTELResourceDetector().detect()\n        ).merge(Resource(attributes))\n        if not resource.attributes.get(SERVICE_NAME, None):\n            default_service_name = \"unknown_service\"\n            process_executable_name = resource.attributes.get(\n                PROCESS_EXECUTABLE_NAME, None\n            )\n            if process_executable_name:\n                default_service_name += \":\" + process_executable_name\n            resource = resource.merge(\n                Resource({SERVICE_NAME: default_service_name})\n            )\n        return resource\n\n    @staticmethod\n    def create_empty() -> \"Resource\":\n        return _EMPTY_RESOURCE\n\n    @property\n    def attributes(self) -> Attributes:\n        return self._attributes.copy()\n\n    def merge(self, other: \"Resource\") -> \"Resource\":\n        \"\"\"Merges this resource and an updating resource into a new `Resource`.\n\n        If a key exists on both the old and updating resource, the value of the\n        updating resource will override the old resource value.\n\n        Args:\n            other: The other resource to be merged.\n\n        Returns:\n            The newly-created Resource.\n        \"\"\"\n        merged_attributes = self.attributes\n        merged_attributes.update(other.attributes)\n        return Resource(merged_attributes)\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, Resource):\n            return False\n        return self._attributes == other._attributes\n\n    def __hash__(self):\n        return hash(dumps(self._attributes, sort_keys=True))\n\n\n_EMPTY_RESOURCE = Resource({})\n_DEFAULT_RESOURCE = Resource(\n    {\n        TELEMETRY_SDK_LANGUAGE: \"python\",\n        TELEMETRY_SDK_NAME: \"opentelemetry\",\n        TELEMETRY_SDK_VERSION: OPENTELEMETRY_SDK_VERSION,\n    }\n)\n\n\nclass ResourceDetector(abc.ABC):\n    def __init__(self, raise_on_error=False):\n        self.raise_on_error = raise_on_error\n\n    @abc.abstractmethod\n    def detect(self) -> \"Resource\":\n        raise NotImplementedError()\n\n\nclass OTELResourceDetector(ResourceDetector):\n    # pylint: disable=no-self-use\n    def detect(self) -> \"Resource\":\n        env_resources_items = os.environ.get(OTEL_RESOURCE_ATTRIBUTES)\n        env_resource_map = {}\n        if env_resources_items:\n            env_resource_map = {\n                key.strip(): value.strip()\n                for key, value in (\n                    item.split(\"=\") for item in env_resources_items.split(\",\")\n                )\n            }\n        return Resource(env_resource_map)\n\n\ndef get_aggregated_resources(\n    detectors: typing.List[\"ResourceDetector\"],\n    initial_resource: typing.Optional[Resource] = None,\n    timeout=5,\n) -> \"Resource\":\n    \"\"\"Retrieves resources from detectors in the order that they were passed\n\n    :param detectors: List of resources in order of priority\n    :param initial_resource: Static resource. This has highest priority\n    :param timeout: Number of seconds to wait for each detector to return\n    :return:\n    \"\"\"\n    final_resource = initial_resource or _EMPTY_RESOURCE\n    detectors = [OTELResourceDetector()] + detectors\n\n    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:\n        futures = [executor.submit(detector.detect) for detector in detectors]\n        for detector_ind, future in enumerate(futures):\n            detector = detectors[detector_ind]\n            try:\n                detected_resources = future.result(timeout=timeout)\n            # pylint: disable=broad-except\n            except Exception as ex:\n                if detector.raise_on_error:\n                    raise ex\n                logger.warning(\n                    \"Exception %s in detector %s, ignoring\", ex, detector\n                )\n                detected_resources = _EMPTY_RESOURCE\n            finally:\n                final_resource = final_resource.merge(detected_resources)\n    return final_resource\n", "path": "opentelemetry-sdk/src/opentelemetry/sdk/resources/__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\"\"\"\nThis package implements `OpenTelemetry Resources\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#resource-sdk>`_:\n\n    *A Resource is an immutable representation of the entity producing\n    telemetry. For example, a process producing telemetry that is running in\n    a container on Kubernetes has a Pod name, it is in a namespace and\n    possibly is part of a Deployment which also has a name. All three of\n    these attributes can be included in the Resource.*\n\nResource objects are created with `Resource.create`, which accepts attributes\n(key-values). Resource attributes can also be passed at process invocation in\nthe :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable. You should\nregister your resource with the  `opentelemetry.sdk.trace.TracerProvider` by\npassing them into their constructors. The `Resource` passed to a provider is\navailable to the exporter, which can send on this information as it sees fit.\n\n.. code-block:: python\n\n    trace.set_tracer_provider(\n        TracerProvider(\n            resource=Resource.create({\n                \"service.name\": \"shoppingcart\",\n                \"service.instance.id\": \"instance-12\",\n            }),\n        ),\n    )\n    print(trace.get_tracer_provider().resource.attributes)\n\n    {'telemetry.sdk.language': 'python',\n    'telemetry.sdk.name': 'opentelemetry',\n    'telemetry.sdk.version': '0.13.dev0',\n    'service.name': 'shoppingcart',\n    'service.instance.id': 'instance-12'}\n\nNote that the OpenTelemetry project documents certain `\"standard attributes\"\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md>`_\nthat have prescribed semantic meanings, for example ``service.name`` in the\nabove example.\n\n.. envvar:: OTEL_RESOURCE_ATTRIBUTES\n\nThe :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable allows resource\nattributes to be passed to the SDK at process invocation. The attributes from\n:envvar:`OTEL_RESOURCE_ATTRIBUTES` are merged with those passed to\n`Resource.create`, meaning :envvar:`OTEL_RESOURCE_ATTRIBUTES` takes *lower*\npriority. Attributes should be in the format ``key1=value1,key2=value2``.\nAdditional details are available `in the specification\n<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable>`_.\n\n.. code-block:: console\n\n    $ OTEL_RESOURCE_ATTRIBUTES=\"service.name=shoppingcard,will_be_overridden=foo\" python - <<EOF\n    import pprint\n    from opentelemetry.sdk.resources import Resource\n    pprint.pprint(Resource.create({\"will_be_overridden\": \"bar\"}).attributes)\n    EOF\n    {'service.name': 'shoppingcard',\n    'telemetry.sdk.language': 'python',\n    'telemetry.sdk.name': 'opentelemetry',\n    'telemetry.sdk.version': '0.13.dev0',\n    'will_be_overridden': 'bar'}\n \"\"\"\n\nimport abc\nimport concurrent.futures\nimport logging\nimport os\nimport typing\nfrom json import dumps\n\nimport pkg_resources\n\nfrom opentelemetry.sdk.environment_variables import OTEL_RESOURCE_ATTRIBUTES\n\nLabelValue = typing.Union[str, bool, int, float]\nAttributes = typing.Dict[str, LabelValue]\nlogger = logging.getLogger(__name__)\n\n\nCLOUD_PROVIDER = \"cloud.provider\"\nCLOUD_ACCOUNT_ID = \"cloud.account.id\"\nCLOUD_REGION = \"cloud.region\"\nCLOUD_ZONE = \"cloud.zone\"\nCONTAINER_NAME = \"container.name\"\nCONTAINER_ID = \"container.id\"\nCONTAINER_IMAGE_NAME = \"container.image.name\"\nCONTAINER_IMAGE_TAG = \"container.image.tag\"\nDEPLOYMENT_ENVIRONMENT = \"deployment.environment\"\nFAAS_NAME = \"faas.name\"\nFAAS_ID = \"faas.id\"\nFAAS_VERSION = \"faas.version\"\nFAAS_INSTANCE = \"faas.instance\"\nHOST_NAME = \"host.name\"\nHOST_TYPE = \"host.type\"\nHOST_IMAGE_NAME = \"host.image.name\"\nHOST_IMAGE_ID = \"host.image.id\"\nHOST_IMAGE_VERSION = \"host.image.version\"\nKUBERNETES_CLUSTER_NAME = \"k8s.cluster.name\"\nKUBERNETES_NAMESPACE_NAME = \"k8s.namespace.name\"\nKUBERNETES_POD_UID = \"k8s.pod.uid\"\nKUBERNETES_POD_NAME = \"k8s.pod.name\"\nKUBERNETES_CONTAINER_NAME = \"k8s.container.name\"\nKUBERNETES_REPLICA_SET_UID = \"k8s.replicaset.uid\"\nKUBERNETES_REPLICA_SET_NAME = \"k8s.replicaset.name\"\nKUBERNETES_DEPLOYMENT_UID = \"k8s.deployment.uid\"\nKUBERNETES_DEPLOYMENT_NAME = \"k8s.deployment.name\"\nKUBERNETES_STATEFUL_SET_UID = \"k8s.statefulset.uid\"\nKUBERNETES_STATEFUL_SET_NAME = \"k8s.statefulset.name\"\nKUBERNETES_DAEMON_SET_UID = \"k8s.daemonset.uid\"\nKUBERNETES_DAEMON_SET_NAME = \"k8s.daemonset.name\"\nKUBERNETES_JOB_UID = \"k8s.job.uid\"\nKUBERNETES_JOB_NAME = \"k8s.job.name\"\nKUBERNETES_CRON_JOB_UID = \"k8s.cronjob.uid\"\nKUBERNETES_CRON_JOB_NAME = \"k8s.cronjob.name\"\nOS_TYPE = \"os.type\"\nOS_DESCRIPTION = \"os.description\"\nPROCESS_PID = \"process.pid\"\nPROCESS_EXECUTABLE_NAME = \"process.executable.name\"\nPROCESS_EXECUTABLE_PATH = \"process.executable.path\"\nPROCESS_COMMAND = \"process.command\"\nPROCESS_COMMAND_LINE = \"process.command_line\"\nPROCESS_COMMAND_ARGS = \"process.command_args\"\nPROCESS_OWNER = \"process.owner\"\nPROCESS_RUNTIME_NAME = \"process.runtime.name\"\nPROCESS_RUNTIME_VERSION = \"process.runtime.version\"\nPROCESS_RUNTIME_DESCRIPTION = \"process.runtime.description\"\nSERVICE_NAME = \"service.name\"\nSERVICE_NAMESPACE = \"service.namespace\"\nSERVICE_INSTANCE_ID = \"service.instance.id\"\nSERVICE_VERSION = \"service.version\"\nTELEMETRY_SDK_NAME = \"telemetry.sdk.name\"\nTELEMETRY_SDK_VERSION = \"telemetry.sdk.version\"\nTELEMETRY_AUTO_VERSION = \"telemetry.auto.version\"\nTELEMETRY_SDK_LANGUAGE = \"telemetry.sdk.language\"\n\n\nOPENTELEMETRY_SDK_VERSION = pkg_resources.get_distribution(\n    \"opentelemetry-sdk\"\n).version\n\n\nclass Resource:\n    \"\"\"A Resource is an immutable representation of the entity producing telemetry as Attributes.\"\"\"\n\n    def __init__(self, attributes: Attributes):\n        self._attributes = attributes.copy()\n\n    @staticmethod\n    def create(attributes: typing.Optional[Attributes] = None) -> \"Resource\":\n        \"\"\"Creates a new `Resource` from attributes.\n\n        Args:\n            attributes: Optional zero or more key-value pairs.\n\n        Returns:\n            The newly-created Resource.\n        \"\"\"\n        if not attributes:\n            attributes = {}\n        resource = _DEFAULT_RESOURCE.merge(\n            OTELResourceDetector().detect()\n        ).merge(Resource(attributes))\n        if not resource.attributes.get(SERVICE_NAME, None):\n            default_service_name = \"unknown_service\"\n            process_executable_name = resource.attributes.get(\n                PROCESS_EXECUTABLE_NAME, None\n            )\n            if process_executable_name:\n                default_service_name += \":\" + process_executable_name\n            resource = resource.merge(\n                Resource({SERVICE_NAME: default_service_name})\n            )\n        return resource\n\n    @staticmethod\n    def get_empty() -> \"Resource\":\n        return _EMPTY_RESOURCE\n\n    @property\n    def attributes(self) -> Attributes:\n        return self._attributes.copy()\n\n    def merge(self, other: \"Resource\") -> \"Resource\":\n        \"\"\"Merges this resource and an updating resource into a new `Resource`.\n\n        If a key exists on both the old and updating resource, the value of the\n        updating resource will override the old resource value.\n\n        Args:\n            other: The other resource to be merged.\n\n        Returns:\n            The newly-created Resource.\n        \"\"\"\n        merged_attributes = self.attributes\n        merged_attributes.update(other.attributes)\n        return Resource(merged_attributes)\n\n    def __eq__(self, other: object) -> bool:\n        if not isinstance(other, Resource):\n            return False\n        return self._attributes == other._attributes\n\n    def __hash__(self):\n        return hash(dumps(self._attributes, sort_keys=True))\n\n\n_EMPTY_RESOURCE = Resource({})\n_DEFAULT_RESOURCE = Resource(\n    {\n        TELEMETRY_SDK_LANGUAGE: \"python\",\n        TELEMETRY_SDK_NAME: \"opentelemetry\",\n        TELEMETRY_SDK_VERSION: OPENTELEMETRY_SDK_VERSION,\n    }\n)\n\n\nclass ResourceDetector(abc.ABC):\n    def __init__(self, raise_on_error=False):\n        self.raise_on_error = raise_on_error\n\n    @abc.abstractmethod\n    def detect(self) -> \"Resource\":\n        raise NotImplementedError()\n\n\nclass OTELResourceDetector(ResourceDetector):\n    # pylint: disable=no-self-use\n    def detect(self) -> \"Resource\":\n        env_resources_items = os.environ.get(OTEL_RESOURCE_ATTRIBUTES)\n        env_resource_map = {}\n        if env_resources_items:\n            env_resource_map = {\n                key.strip(): value.strip()\n                for key, value in (\n                    item.split(\"=\") for item in env_resources_items.split(\",\")\n                )\n            }\n        return Resource(env_resource_map)\n\n\ndef get_aggregated_resources(\n    detectors: typing.List[\"ResourceDetector\"],\n    initial_resource: typing.Optional[Resource] = None,\n    timeout=5,\n) -> \"Resource\":\n    \"\"\"Retrieves resources from detectors in the order that they were passed\n\n    :param detectors: List of resources in order of priority\n    :param initial_resource: Static resource. This has highest priority\n    :param timeout: Number of seconds to wait for each detector to return\n    :return:\n    \"\"\"\n    final_resource = initial_resource or _EMPTY_RESOURCE\n    detectors = [OTELResourceDetector()] + detectors\n\n    with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:\n        futures = [executor.submit(detector.detect) for detector in detectors]\n        for detector_ind, future in enumerate(futures):\n            detector = detectors[detector_ind]\n            try:\n                detected_resources = future.result(timeout=timeout)\n            # pylint: disable=broad-except\n            except Exception as ex:\n                if detector.raise_on_error:\n                    raise ex\n                logger.warning(\n                    \"Exception %s in detector %s, ignoring\", ex, detector\n                )\n                detected_resources = _EMPTY_RESOURCE\n            finally:\n                final_resource = final_resource.merge(detected_resources)\n    return final_resource\n", "path": "opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py"}]}