prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Too noise logging about telemetry
  Hello,
  
  In the Apache Airflow project, we use the BigQuery library, but recently we've started to see annoying log message when the library is loaded. It is enough that the library is loaded and there is an message every time. 
  
  In my opinion, this message should be of a lower level (DEBUG) so that it is not displayed much less often or is displayed only when the client is initialized. 
  ```
  import logging
  logging.basicConfig(level=logging.INFO)
  
  from google.cloud import bigquery
  ```
  Output: 
  ```
  INFO:google.cloud.bigquery.opentelemetry_tracing:This service is instrumented using OpenTelemetry. OpenTelemetry could not be imported; please add opentelemetry-api and opentelemetry-instrumentation packages in order to get BigQuery Tracing data.
  ```
  
  Related issue: https://github.com/apache/airflow/issues/13131
  
  CC: @tswast 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `google/cloud/bigquery/opentelemetry_tracing.py`
  Content:
  ```
  1 # Copyright 2020 Google LLC
  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 import logging
  16 from contextlib import contextmanager
  17 from google.api_core.exceptions import GoogleAPICallError
  18 
  19 logger = logging.getLogger(__name__)
  20 try:
  21     from opentelemetry import trace
  22     from opentelemetry.instrumentation.utils import http_status_to_canonical_code
  23     from opentelemetry.trace.status import Status
  24 
  25     HAS_OPENTELEMETRY = True
  26 
  27 except ImportError:
  28     logger.info(
  29         "This service is instrumented using OpenTelemetry. "
  30         "OpenTelemetry could not be imported; please "
  31         "add opentelemetry-api and opentelemetry-instrumentation "
  32         "packages in order to get BigQuery Tracing data."
  33     )
  34 
  35     HAS_OPENTELEMETRY = False
  36 
  37 _default_attributes = {
  38     "db.system": "BigQuery"
  39 }  # static, default values assigned to all spans
  40 
  41 
  42 @contextmanager
  43 def create_span(name, attributes=None, client=None, job_ref=None):
  44     """Creates a ContextManager for a Span to be exported to the configured exporter.
  45         If no configuration exists yields None.
  46 
  47             Args:
  48                 name (str): Name that will be set for the span being created
  49                 attributes (Optional[dict]):
  50                     Additional attributes that pertain to
  51                     the specific API call (i.e. not a default attribute)
  52                 client (Optional[google.cloud.bigquery.client.Client]):
  53                     Pass in a Client object to extract any attributes that may be
  54                     relevant to it and add them to the created spans.
  55                 job_ref (Optional[google.cloud.bigquery.job._AsyncJob])
  56                     Pass in a _AsyncJob object to extract any attributes that may be
  57                     relevant to it and add them to the created spans.
  58 
  59             Yields:
  60                 opentelemetry.trace.Span: Yields the newly created Span.
  61 
  62             Raises:
  63                 google.api_core.exceptions.GoogleAPICallError:
  64                     Raised if a span could not be yielded or issue with call to
  65                     OpenTelemetry.
  66             """
  67     final_attributes = _get_final_span_attributes(attributes, client, job_ref)
  68     if not HAS_OPENTELEMETRY:
  69         yield None
  70         return
  71     tracer = trace.get_tracer(__name__)
  72 
  73     # yield new span value
  74     with tracer.start_as_current_span(name=name, attributes=final_attributes) as span:
  75         try:
  76             yield span
  77         except GoogleAPICallError as error:
  78             if error.code is not None:
  79                 span.set_status(Status(http_status_to_canonical_code(error.code)))
  80             raise
  81 
  82 
  83 def _get_final_span_attributes(attributes=None, client=None, job_ref=None):
  84     final_attributes = {}
  85     final_attributes.update(_default_attributes.copy())
  86     if client:
  87         client_attributes = _set_client_attributes(client)
  88         final_attributes.update(client_attributes)
  89     if job_ref:
  90         job_attributes = _set_job_attributes(job_ref)
  91         final_attributes.update(job_attributes)
  92     if attributes:
  93         final_attributes.update(attributes)
  94     return final_attributes
  95 
  96 
  97 def _set_client_attributes(client):
  98     return {"db.name": client.project, "location": client.location}
  99 
  100 
  101 def _set_job_attributes(job_ref):
  102     job_attributes = {
  103         "db.name": job_ref.project,
  104         "location": job_ref.location,
  105         "num_child_jobs": job_ref.num_child_jobs,
  106         "job_id": job_ref.job_id,
  107         "parent_job_id": job_ref.parent_job_id,
  108         "state": job_ref.state,
  109     }
  110 
  111     job_attributes["hasErrors"] = job_ref.error_result is not None
  112 
  113     if job_ref.created is not None:
  114         job_attributes["timeCreated"] = job_ref.created.isoformat()
  115 
  116     if job_ref.started is not None:
  117         job_attributes["timeStarted"] = job_ref.started.isoformat()
  118 
  119     if job_ref.ended is not None:
  120         job_attributes["timeEnded"] = job_ref.ended.isoformat()
  121 
  122     return job_attributes
  123
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/google/cloud/bigquery/opentelemetry_tracing.py b/google/cloud/bigquery/opentelemetry_tracing.py
  --- a/google/cloud/bigquery/opentelemetry_tracing.py
  +++ b/google/cloud/bigquery/opentelemetry_tracing.py
  @@ -23,16 +23,11 @@
       from opentelemetry.trace.status import Status
   
       HAS_OPENTELEMETRY = True
  +    _warned_telemetry = True
   
   except ImportError:
  -    logger.info(
  -        "This service is instrumented using OpenTelemetry. "
  -        "OpenTelemetry could not be imported; please "
  -        "add opentelemetry-api and opentelemetry-instrumentation "
  -        "packages in order to get BigQuery Tracing data."
  -    )
  -
       HAS_OPENTELEMETRY = False
  +    _warned_telemetry = False
   
   _default_attributes = {
       "db.system": "BigQuery"
  @@ -64,8 +59,18 @@
                       Raised if a span could not be yielded or issue with call to
                       OpenTelemetry.
               """
  +    global _warned_telemetry
       final_attributes = _get_final_span_attributes(attributes, client, job_ref)
       if not HAS_OPENTELEMETRY:
  +        if not _warned_telemetry:
  +            logger.debug(
  +                "This service is instrumented using OpenTelemetry. "
  +                "OpenTelemetry could not be imported; please "
  +                "add opentelemetry-api and opentelemetry-instrumentation "
  +                "packages in order to get BigQuery Tracing data."
  +            )
  +            _warned_telemetry = True
  +
           yield None
           return
       tracer = trace.get_tracer(__name__)
  
verification_info: {"golden_diff": "diff --git a/google/cloud/bigquery/opentelemetry_tracing.py b/google/cloud/bigquery/opentelemetry_tracing.py\n--- a/google/cloud/bigquery/opentelemetry_tracing.py\n+++ b/google/cloud/bigquery/opentelemetry_tracing.py\n@@ -23,16 +23,11 @@\n     from opentelemetry.trace.status import Status\n \n     HAS_OPENTELEMETRY = True\n+    _warned_telemetry = True\n \n except ImportError:\n-    logger.info(\n-        \"This service is instrumented using OpenTelemetry. \"\n-        \"OpenTelemetry could not be imported; please \"\n-        \"add opentelemetry-api and opentelemetry-instrumentation \"\n-        \"packages in order to get BigQuery Tracing data.\"\n-    )\n-\n     HAS_OPENTELEMETRY = False\n+    _warned_telemetry = False\n \n _default_attributes = {\n     \"db.system\": \"BigQuery\"\n@@ -64,8 +59,18 @@\n                     Raised if a span could not be yielded or issue with call to\n                     OpenTelemetry.\n             \"\"\"\n+    global _warned_telemetry\n     final_attributes = _get_final_span_attributes(attributes, client, job_ref)\n     if not HAS_OPENTELEMETRY:\n+        if not _warned_telemetry:\n+            logger.debug(\n+                \"This service is instrumented using OpenTelemetry. \"\n+                \"OpenTelemetry could not be imported; please \"\n+                \"add opentelemetry-api and opentelemetry-instrumentation \"\n+                \"packages in order to get BigQuery Tracing data.\"\n+            )\n+            _warned_telemetry = True\n+\n         yield None\n         return\n     tracer = trace.get_tracer(__name__)\n", "issue": "Too noise logging about telemetry\nHello,\r\n\r\nIn the Apache Airflow project, we use the BigQuery library, but recently we've started to see annoying log message when the library is loaded. It is enough that the library is loaded and there is an message every time. \r\n\r\nIn my opinion, this message should be of a lower level (DEBUG) so that it is not displayed much less often or is displayed only when the client is initialized. \r\n```\r\nimport logging\r\nlogging.basicConfig(level=logging.INFO)\r\n\r\nfrom google.cloud import bigquery\r\n```\r\nOutput: \r\n```\r\nINFO:google.cloud.bigquery.opentelemetry_tracing:This service is instrumented using OpenTelemetry. OpenTelemetry could not be imported; please add opentelemetry-api and opentelemetry-instrumentation packages in order to get BigQuery Tracing data.\r\n```\r\n\r\nRelated issue: https://github.com/apache/airflow/issues/13131\r\n\r\nCC: @tswast \n", "before_files": [{"content": "# Copyright 2020 Google LLC\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\nimport logging\nfrom contextlib import contextmanager\nfrom google.api_core.exceptions import GoogleAPICallError\n\nlogger = logging.getLogger(__name__)\ntry:\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.utils import http_status_to_canonical_code\n    from opentelemetry.trace.status import Status\n\n    HAS_OPENTELEMETRY = True\n\nexcept ImportError:\n    logger.info(\n        \"This service is instrumented using OpenTelemetry. \"\n        \"OpenTelemetry could not be imported; please \"\n        \"add opentelemetry-api and opentelemetry-instrumentation \"\n        \"packages in order to get BigQuery Tracing data.\"\n    )\n\n    HAS_OPENTELEMETRY = False\n\n_default_attributes = {\n    \"db.system\": \"BigQuery\"\n}  # static, default values assigned to all spans\n\n\n@contextmanager\ndef create_span(name, attributes=None, client=None, job_ref=None):\n    \"\"\"Creates a ContextManager for a Span to be exported to the configured exporter.\n        If no configuration exists yields None.\n\n            Args:\n                name (str): Name that will be set for the span being created\n                attributes (Optional[dict]):\n                    Additional attributes that pertain to\n                    the specific API call (i.e. not a default attribute)\n                client (Optional[google.cloud.bigquery.client.Client]):\n                    Pass in a Client object to extract any attributes that may be\n                    relevant to it and add them to the created spans.\n                job_ref (Optional[google.cloud.bigquery.job._AsyncJob])\n                    Pass in a _AsyncJob object to extract any attributes that may be\n                    relevant to it and add them to the created spans.\n\n            Yields:\n                opentelemetry.trace.Span: Yields the newly created Span.\n\n            Raises:\n                google.api_core.exceptions.GoogleAPICallError:\n                    Raised if a span could not be yielded or issue with call to\n                    OpenTelemetry.\n            \"\"\"\n    final_attributes = _get_final_span_attributes(attributes, client, job_ref)\n    if not HAS_OPENTELEMETRY:\n        yield None\n        return\n    tracer = trace.get_tracer(__name__)\n\n    # yield new span value\n    with tracer.start_as_current_span(name=name, attributes=final_attributes) as span:\n        try:\n            yield span\n        except GoogleAPICallError as error:\n            if error.code is not None:\n                span.set_status(Status(http_status_to_canonical_code(error.code)))\n            raise\n\n\ndef _get_final_span_attributes(attributes=None, client=None, job_ref=None):\n    final_attributes = {}\n    final_attributes.update(_default_attributes.copy())\n    if client:\n        client_attributes = _set_client_attributes(client)\n        final_attributes.update(client_attributes)\n    if job_ref:\n        job_attributes = _set_job_attributes(job_ref)\n        final_attributes.update(job_attributes)\n    if attributes:\n        final_attributes.update(attributes)\n    return final_attributes\n\n\ndef _set_client_attributes(client):\n    return {\"db.name\": client.project, \"location\": client.location}\n\n\ndef _set_job_attributes(job_ref):\n    job_attributes = {\n        \"db.name\": job_ref.project,\n        \"location\": job_ref.location,\n        \"num_child_jobs\": job_ref.num_child_jobs,\n        \"job_id\": job_ref.job_id,\n        \"parent_job_id\": job_ref.parent_job_id,\n        \"state\": job_ref.state,\n    }\n\n    job_attributes[\"hasErrors\"] = job_ref.error_result is not None\n\n    if job_ref.created is not None:\n        job_attributes[\"timeCreated\"] = job_ref.created.isoformat()\n\n    if job_ref.started is not None:\n        job_attributes[\"timeStarted\"] = job_ref.started.isoformat()\n\n    if job_ref.ended is not None:\n        job_attributes[\"timeEnded\"] = job_ref.ended.isoformat()\n\n    return job_attributes\n", "path": "google/cloud/bigquery/opentelemetry_tracing.py"}], "after_files": [{"content": "# Copyright 2020 Google LLC\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\nimport logging\nfrom contextlib import contextmanager\nfrom google.api_core.exceptions import GoogleAPICallError\n\nlogger = logging.getLogger(__name__)\ntry:\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.utils import http_status_to_canonical_code\n    from opentelemetry.trace.status import Status\n\n    HAS_OPENTELEMETRY = True\n    _warned_telemetry = True\n\nexcept ImportError:\n    HAS_OPENTELEMETRY = False\n    _warned_telemetry = False\n\n_default_attributes = {\n    \"db.system\": \"BigQuery\"\n}  # static, default values assigned to all spans\n\n\n@contextmanager\ndef create_span(name, attributes=None, client=None, job_ref=None):\n    \"\"\"Creates a ContextManager for a Span to be exported to the configured exporter.\n        If no configuration exists yields None.\n\n            Args:\n                name (str): Name that will be set for the span being created\n                attributes (Optional[dict]):\n                    Additional attributes that pertain to\n                    the specific API call (i.e. not a default attribute)\n                client (Optional[google.cloud.bigquery.client.Client]):\n                    Pass in a Client object to extract any attributes that may be\n                    relevant to it and add them to the created spans.\n                job_ref (Optional[google.cloud.bigquery.job._AsyncJob])\n                    Pass in a _AsyncJob object to extract any attributes that may be\n                    relevant to it and add them to the created spans.\n\n            Yields:\n                opentelemetry.trace.Span: Yields the newly created Span.\n\n            Raises:\n                google.api_core.exceptions.GoogleAPICallError:\n                    Raised if a span could not be yielded or issue with call to\n                    OpenTelemetry.\n            \"\"\"\n    global _warned_telemetry\n    final_attributes = _get_final_span_attributes(attributes, client, job_ref)\n    if not HAS_OPENTELEMETRY:\n        if not _warned_telemetry:\n            logger.debug(\n                \"This service is instrumented using OpenTelemetry. \"\n                \"OpenTelemetry could not be imported; please \"\n                \"add opentelemetry-api and opentelemetry-instrumentation \"\n                \"packages in order to get BigQuery Tracing data.\"\n            )\n            _warned_telemetry = True\n\n        yield None\n        return\n    tracer = trace.get_tracer(__name__)\n\n    # yield new span value\n    with tracer.start_as_current_span(name=name, attributes=final_attributes) as span:\n        try:\n            yield span\n        except GoogleAPICallError as error:\n            if error.code is not None:\n                span.set_status(Status(http_status_to_canonical_code(error.code)))\n            raise\n\n\ndef _get_final_span_attributes(attributes=None, client=None, job_ref=None):\n    final_attributes = {}\n    final_attributes.update(_default_attributes.copy())\n    if client:\n        client_attributes = _set_client_attributes(client)\n        final_attributes.update(client_attributes)\n    if job_ref:\n        job_attributes = _set_job_attributes(job_ref)\n        final_attributes.update(job_attributes)\n    if attributes:\n        final_attributes.update(attributes)\n    return final_attributes\n\n\ndef _set_client_attributes(client):\n    return {\"db.name\": client.project, \"location\": client.location}\n\n\ndef _set_job_attributes(job_ref):\n    job_attributes = {\n        \"db.name\": job_ref.project,\n        \"location\": job_ref.location,\n        \"num_child_jobs\": job_ref.num_child_jobs,\n        \"job_id\": job_ref.job_id,\n        \"parent_job_id\": job_ref.parent_job_id,\n        \"state\": job_ref.state,\n    }\n\n    job_attributes[\"hasErrors\"] = job_ref.error_result is not None\n\n    if job_ref.created is not None:\n        job_attributes[\"timeCreated\"] = job_ref.created.isoformat()\n\n    if job_ref.started is not None:\n        job_attributes[\"timeStarted\"] = job_ref.started.isoformat()\n\n    if job_ref.ended is not None:\n        job_attributes[\"timeEnded\"] = job_ref.ended.isoformat()\n\n    return job_attributes\n", "path": "google/cloud/bigquery/opentelemetry_tracing.py"}]}