We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add `otelTraceSampled` field to LogEntry for OLTP Logging Instrumentation module
Before opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first.

**Is your feature request related to a problem?**
Getting span id and trace id in the log record is a must. Cloud provider libraries, e.g. Google Cloud Logging also provides a `logging.googleapis.com/trace_sampled` field under structured logging, which can be populated using this library. 


**Describe the solution you'd like**
Add a `record.otelTraceSampled` field similar to `record.otelSpanID` and `record.otelTraceID` in the log entry using the `trace_flags` property in `SpanContext`. 

**Describe alternatives you've considered**
Manually injecting the value of `trace_flags` property into the log record by using the current `SpanContext`.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.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 DEFAULT_LOGGING_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s"
16 
17 
18 _MODULE_DOC = """
19 The OpenTelemetry ``logging`` integration automatically injects tracing context into log statements.
20 
21 The integration registers a custom log record factory with the the standard library logging module that automatically inject
22 tracing context into log record objects. Optionally, the integration can also call ``logging.basicConfig()`` to set a logging
23 format with placeholders for span ID, trace ID and service name.
24 
25 The following keys are injected into log record objects by the factory:
26 
27 - ``otelSpanID``
28 - ``otelTraceID``
29 - ``otelServiceName``
30 
31 The integration uses the following logging format by default:
32 
33 .. code-block::
34 
35     {default_logging_format}
36 
37 Enable trace context injection
38 ------------------------------
39 
40 The integration is opt-in and must be enabled explicitly by setting the environment variable ``OTEL_PYTHON_LOG_CORRELATION`` to ``true``.
41 
42 The integration always registers the custom factory that injects the tracing context into the log record objects. Setting
43 ``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` calls ``logging.basicConfig()`` to set a logging format that actually makes
44 use of the injected variables.
45 
46 
47 Environment variables
48 ---------------------
49 
50 .. envvar:: OTEL_PYTHON_LOG_CORRELATION
51 
52 This env var must be set to ``true`` in order to enable trace context injection into logs by calling ``logging.basicConfig()`` and
53 setting a logging format that makes use of the injected tracing variables.
54 
55 Alternatively, ``set_logging_format`` argument can be set to ``True`` when initializing the ``LoggingInstrumentor`` class to achieve the
56 same effect.
57 
58 .. code-block::
59 
60     LoggingInstrumentor(set_logging_format=True)
61 
62 The default value is ``false``.
63 
64 .. envvar:: OTEL_PYTHON_LOG_FORMAT
65 
66 This env var can be used to instruct the instrumentation to use a custom logging format.
67 
68 Alternatively, a custom logging format can be passed to the ``LoggingInstrumentor`` as the ``logging_format`` argument. For example:
69 
70 .. code-block::
71 
72     LoggingInstrumentor(logging_format='%(msg)s [span_id=%(span_id)s]')
73 
74 
75 The default value is:
76 
77 .. code-block::
78 
79     {default_logging_format}
80 
81 .. envvar:: OTEL_PYTHON_LOG_LEVEL
82 
83 This env var can be used to set a custom logging level.
84 
85 Alternatively, log level can be passed to the ``LoggingInstrumentor`` during initialization. For example:
86 
87 .. code-block::
88 
89     LoggingInstrumentor(log_level=logging.DEBUG)
90 
91 
92 The default value is ``info``.
93 
94 Options are:
95 
96 - ``info``
97 - ``error``
98 - ``debug``
99 - ``warning``
100 
101 Manually calling logging.basicConfig
102 ------------------------------------
103 
104 ``logging.basicConfig()`` can be called to set a global logging level and format. Only the first ever call has any effect on the global logger.
105 Any subsequent calls have no effect and do not override a previously configured global logger. This integration calls ``logging.basicConfig()`` for you
106 when ``OTEL_PYTHON_LOG_CORRELATION`` is set to ``true``. It uses the format and level specified by ``OTEL_PYTHON_LOG_FORMAT`` and ``OTEL_PYTHON_LOG_LEVEL``
107 environment variables respectively.
108 
109 If you code or some other library/framework you are using calls logging.basicConfig before this integration is enabled, then this integration's logging
110 format will not be used and log statements will not contain tracing context. For this reason, you'll need to make sure this integration is enabled as early
111 as possible in the service lifecycle or your framework is configured to use a logging format with placeholders for tracing context. This can be achieved by
112 adding the following placeholders to your logging format:
113 
114 .. code-block::
115 
116     %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s
117 
118 
119 
120 API
121 -----
122 
123 .. code-block:: python
124 
125     from opentelemetry.instrumentation.logging import LoggingInstrumentor
126 
127     LoggingInstrumentor().instrument(set_logging_format=True)
128 
129 
130 Note
131 -----
132 
133 If you do not set ``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` but instead set the logging format manually or through your framework, you must ensure that this
134 integration is enabled before you set the logging format. This is important because unless the integration is enabled, the tracing context variables
135 are not injected into the log record objects. This means any attempted log statements made after setting the logging format and before enabling this integration
136 will result in KeyError exceptions. Such exceptions are automatically swallowed by the logging module and do not result in crashes but you may still lose out
137 on important log messages.
138 """.format(
139     default_logging_format=DEFAULT_LOGGING_FORMAT
140 )
141
```

Path: `instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__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 # pylint: disable=empty-docstring,no-value-for-parameter,no-member,no-name-in-module
16 
17 import logging  # pylint: disable=import-self
18 from os import environ
19 from typing import Collection
20 
21 from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
22 from opentelemetry.instrumentation.logging.constants import (
23     _MODULE_DOC,
24     DEFAULT_LOGGING_FORMAT,
25 )
26 from opentelemetry.instrumentation.logging.environment_variables import (
27     OTEL_PYTHON_LOG_CORRELATION,
28     OTEL_PYTHON_LOG_FORMAT,
29     OTEL_PYTHON_LOG_LEVEL,
30 )
31 from opentelemetry.instrumentation.logging.package import _instruments
32 from opentelemetry.trace import (
33     INVALID_SPAN,
34     INVALID_SPAN_CONTEXT,
35     get_current_span,
36     get_tracer_provider,
37 )
38 
39 __doc__ = _MODULE_DOC
40 
41 LEVELS = {
42     "debug": logging.DEBUG,
43     "info": logging.INFO,
44     "warning": logging.WARNING,
45     "error": logging.ERROR,
46 }
47 
48 
49 class LoggingInstrumentor(BaseInstrumentor):  # pylint: disable=empty-docstring
50     __doc__ = f"""An instrumentor for stdlib logging module.
51 
52     This instrumentor injects tracing context into logging records and optionally sets the global logging format to the following:
53 
54     .. code-block::
55 
56         {DEFAULT_LOGGING_FORMAT}
57 
58         def log_hook(span: Span, record: LogRecord):
59                 if span and span.is_recording():
60                     record.custom_user_attribute_from_log_hook = "some-value"
61 
62     Args:
63         tracer_provider: Tracer provider instance that can be used to fetch a tracer.
64         set_logging_format: When set to True, it calls logging.basicConfig() and sets a logging format.
65         logging_format: Accepts a string and sets it as the logging format when set_logging_format
66             is set to True.
67         log_level: Accepts one of the following values and sets the logging level to it.
68             logging.INFO
69             logging.DEBUG
70             logging.WARN
71             logging.ERROR
72             logging.FATAL
73         log_hook: execute custom logic when record is created
74 
75     See `BaseInstrumentor`
76     """
77 
78     _old_factory = None
79     _log_hook = None
80 
81     def instrumentation_dependencies(self) -> Collection[str]:
82         return _instruments
83 
84     def _instrument(self, **kwargs):
85         provider = kwargs.get("tracer_provider", None) or get_tracer_provider()
86         old_factory = logging.getLogRecordFactory()
87         LoggingInstrumentor._old_factory = old_factory
88         LoggingInstrumentor._log_hook = kwargs.get("log_hook", None)
89 
90         service_name = None
91 
92         def record_factory(*args, **kwargs):
93             record = old_factory(*args, **kwargs)
94 
95             record.otelSpanID = "0"
96             record.otelTraceID = "0"
97 
98             nonlocal service_name
99             if service_name is None:
100                 resource = getattr(provider, "resource", None)
101                 if resource:
102                     service_name = (
103                         resource.attributes.get("service.name") or ""
104                     )
105                 else:
106                     service_name = ""
107 
108             record.otelServiceName = service_name
109 
110             span = get_current_span()
111             if span != INVALID_SPAN:
112                 ctx = span.get_span_context()
113                 if ctx != INVALID_SPAN_CONTEXT:
114                     record.otelSpanID = format(ctx.span_id, "016x")
115                     record.otelTraceID = format(ctx.trace_id, "032x")
116                     if callable(LoggingInstrumentor._log_hook):
117                         try:
118                             LoggingInstrumentor._log_hook(  # pylint: disable=E1102
119                                 span, record
120                             )
121                         except Exception:  # pylint: disable=W0703
122                             pass
123 
124             return record
125 
126         logging.setLogRecordFactory(record_factory)
127 
128         set_logging_format = kwargs.get(
129             "set_logging_format",
130             environ.get(OTEL_PYTHON_LOG_CORRELATION, "false").lower()
131             == "true",
132         )
133 
134         if set_logging_format:
135             log_format = kwargs.get(
136                 "logging_format", environ.get(OTEL_PYTHON_LOG_FORMAT, None)
137             )
138             log_format = log_format or DEFAULT_LOGGING_FORMAT
139 
140             log_level = kwargs.get(
141                 "log_level", LEVELS.get(environ.get(OTEL_PYTHON_LOG_LEVEL))
142             )
143             log_level = log_level or logging.INFO
144 
145             logging.basicConfig(format=log_format, level=log_level)
146 
147     def _uninstrument(self, **kwargs):
148         if LoggingInstrumentor._old_factory:
149             logging.setLogRecordFactory(LoggingInstrumentor._old_factory)
150             LoggingInstrumentor._old_factory = None
151
```
--- 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/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py
@@ -94,6 +94,7 @@
 
             record.otelSpanID = "0"
             record.otelTraceID = "0"
+            record.otelTraceSampled = False
 
             nonlocal service_name
             if service_name is None:
@@ -113,6 +114,7 @@
                 if ctx != INVALID_SPAN_CONTEXT:
                     record.otelSpanID = format(ctx.span_id, "016x")
                     record.otelTraceID = format(ctx.trace_id, "032x")
+                    record.otelTraceSampled = ctx.trace_flags.sampled
                     if callable(LoggingInstrumentor._log_hook):
                         try:
                             LoggingInstrumentor._log_hook(  # pylint: disable=E1102
diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py
--- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py
+++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-DEFAULT_LOGGING_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s"
+DEFAULT_LOGGING_FORMAT = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s"
 
 
 _MODULE_DOC = """
@@ -27,6 +27,7 @@
 - ``otelSpanID``
 - ``otelTraceID``
 - ``otelServiceName``
+- ``otelTraceSampled``
 
 The integration uses the following logging format by default:
 
@@ -113,7 +114,7 @@
 
 .. code-block::
 
-    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s
+    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s %(otelTraceSampled)s

{"golden_diff": "diff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py\n--- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py\n+++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py\n@@ -94,6 +94,7 @@\n \n             record.otelSpanID = \"0\"\n             record.otelTraceID = \"0\"\n+            record.otelTraceSampled = False\n \n             nonlocal service_name\n             if service_name is None:\n@@ -113,6 +114,7 @@\n                 if ctx != INVALID_SPAN_CONTEXT:\n                     record.otelSpanID = format(ctx.span_id, \"016x\")\n                     record.otelTraceID = format(ctx.trace_id, \"032x\")\n+                    record.otelTraceSampled = ctx.trace_flags.sampled\n                     if callable(LoggingInstrumentor._log_hook):\n                         try:\n                             LoggingInstrumentor._log_hook(  # pylint: disable=E1102\ndiff --git a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py\n--- a/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py\n+++ b/instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.py\n@@ -12,7 +12,7 @@\n # See the License for the specific language governing permissions and\n # limitations under the License.\n \n-DEFAULT_LOGGING_FORMAT = \"%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s\"\n+DEFAULT_LOGGING_FORMAT = \"%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s\"\n \n \n _MODULE_DOC = \"\"\"\n@@ -27,6 +27,7 @@\n - ``otelSpanID``\n - ``otelTraceID``\n - ``otelServiceName``\n+- ``otelTraceSampled``\n \n The integration uses the following logging format by default:\n \n@@ -113,7 +114,7 @@\n \n .. code-block::\n \n-    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s\n+    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s %(otelTraceSampled)s\n", "issue": "Add `otelTraceSampled` field to LogEntry for OLTP Logging Instrumentation module\nBefore opening a feature request against this repo, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first.\r\n\r\n**Is your feature request related to a problem?**\r\nGetting span id and trace id in the log record is a must. Cloud provider libraries, e.g. Google Cloud Logging also provides a `logging.googleapis.com/trace_sampled` field under structured logging, which can be populated using this library. \r\n\r\n\r\n**Describe the solution you'd like**\r\nAdd a `record.otelTraceSampled` field similar to `record.otelSpanID` and `record.otelTraceID` in the log entry using the `trace_flags` property in `SpanContext`. \r\n\r\n**Describe alternatives you've considered**\r\nManually injecting the value of `trace_flags` property into the log record by using the current `SpanContext`.\r\n\r\n\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\nDEFAULT_LOGGING_FORMAT = \"%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s] - %(message)s\"\n\n\n_MODULE_DOC = \"\"\"\nThe OpenTelemetry ``logging`` integration automatically injects tracing context into log statements.\n\nThe integration registers a custom log record factory with the the standard library logging module that automatically inject\ntracing context into log record objects. Optionally, the integration can also call ``logging.basicConfig()`` to set a logging\nformat with placeholders for span ID, trace ID and service name.\n\nThe following keys are injected into log record objects by the factory:\n\n- ``otelSpanID``\n- ``otelTraceID``\n- ``otelServiceName``\n\nThe integration uses the following logging format by default:\n\n.. code-block::\n\n    {default_logging_format}\n\nEnable trace context injection\n------------------------------\n\nThe integration is opt-in and must be enabled explicitly by setting the environment variable ``OTEL_PYTHON_LOG_CORRELATION`` to ``true``.\n\nThe integration always registers the custom factory that injects the tracing context into the log record objects. Setting\n``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` calls ``logging.basicConfig()`` to set a logging format that actually makes\nuse of the injected variables.\n\n\nEnvironment variables\n---------------------\n\n.. envvar:: OTEL_PYTHON_LOG_CORRELATION\n\nThis env var must be set to ``true`` in order to enable trace context injection into logs by calling ``logging.basicConfig()`` and\nsetting a logging format that makes use of the injected tracing variables.\n\nAlternatively, ``set_logging_format`` argument can be set to ``True`` when initializing the ``LoggingInstrumentor`` class to achieve the\nsame effect.\n\n.. code-block::\n\n    LoggingInstrumentor(set_logging_format=True)\n\nThe default value is ``false``.\n\n.. envvar:: OTEL_PYTHON_LOG_FORMAT\n\nThis env var can be used to instruct the instrumentation to use a custom logging format.\n\nAlternatively, a custom logging format can be passed to the ``LoggingInstrumentor`` as the ``logging_format`` argument. For example:\n\n.. code-block::\n\n    LoggingInstrumentor(logging_format='%(msg)s [span_id=%(span_id)s]')\n\n\nThe default value is:\n\n.. code-block::\n\n    {default_logging_format}\n\n.. envvar:: OTEL_PYTHON_LOG_LEVEL\n\nThis env var can be used to set a custom logging level.\n\nAlternatively, log level can be passed to the ``LoggingInstrumentor`` during initialization. For example:\n\n.. code-block::\n\n    LoggingInstrumentor(log_level=logging.DEBUG)\n\n\nThe default value is ``info``.\n\nOptions are:\n\n- ``info``\n- ``error``\n- ``debug``\n- ``warning``\n\nManually calling logging.basicConfig\n------------------------------------\n\n``logging.basicConfig()`` can be called to set a global logging level and format. Only the first ever call has any effect on the global logger.\nAny subsequent calls have no effect and do not override a previously configured global logger. This integration calls ``logging.basicConfig()`` for you\nwhen ``OTEL_PYTHON_LOG_CORRELATION`` is set to ``true``. It uses the format and level specified by ``OTEL_PYTHON_LOG_FORMAT`` and ``OTEL_PYTHON_LOG_LEVEL``\nenvironment variables respectively.\n\nIf you code or some other library/framework you are using calls logging.basicConfig before this integration is enabled, then this integration's logging\nformat will not be used and log statements will not contain tracing context. For this reason, you'll need to make sure this integration is enabled as early\nas possible in the service lifecycle or your framework is configured to use a logging format with placeholders for tracing context. This can be achieved by\nadding the following placeholders to your logging format:\n\n.. code-block::\n\n    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s\n\n\n\nAPI\n-----\n\n.. code-block:: python\n\n    from opentelemetry.instrumentation.logging import LoggingInstrumentor\n\n    LoggingInstrumentor().instrument(set_logging_format=True)\n\n\nNote\n-----\n\nIf you do not set ``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` but instead set the logging format manually or through your framework, you must ensure that this\nintegration is enabled before you set the logging format. This is important because unless the integration is enabled, the tracing context variables\nare not injected into the log record objects. This means any attempted log statements made after setting the logging format and before enabling this integration\nwill result in KeyError exceptions. Such exceptions are automatically swallowed by the logging module and do not result in crashes but you may still lose out\non important log messages.\n\"\"\".format(\n    default_logging_format=DEFAULT_LOGGING_FORMAT\n)\n", "path": "instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.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# pylint: disable=empty-docstring,no-value-for-parameter,no-member,no-name-in-module\n\nimport logging  # pylint: disable=import-self\nfrom os import environ\nfrom typing import Collection\n\nfrom opentelemetry.instrumentation.instrumentor import BaseInstrumentor\nfrom opentelemetry.instrumentation.logging.constants import (\n    _MODULE_DOC,\n    DEFAULT_LOGGING_FORMAT,\n)\nfrom opentelemetry.instrumentation.logging.environment_variables import (\n    OTEL_PYTHON_LOG_CORRELATION,\n    OTEL_PYTHON_LOG_FORMAT,\n    OTEL_PYTHON_LOG_LEVEL,\n)\nfrom opentelemetry.instrumentation.logging.package import _instruments\nfrom opentelemetry.trace import (\n    INVALID_SPAN,\n    INVALID_SPAN_CONTEXT,\n    get_current_span,\n    get_tracer_provider,\n)\n\n__doc__ = _MODULE_DOC\n\nLEVELS = {\n    \"debug\": logging.DEBUG,\n    \"info\": logging.INFO,\n    \"warning\": logging.WARNING,\n    \"error\": logging.ERROR,\n}\n\n\nclass LoggingInstrumentor(BaseInstrumentor):  # pylint: disable=empty-docstring\n    __doc__ = f\"\"\"An instrumentor for stdlib logging module.\n\n    This instrumentor injects tracing context into logging records and optionally sets the global logging format to the following:\n\n    .. code-block::\n\n        {DEFAULT_LOGGING_FORMAT}\n\n        def log_hook(span: Span, record: LogRecord):\n                if span and span.is_recording():\n                    record.custom_user_attribute_from_log_hook = \"some-value\"\n\n    Args:\n        tracer_provider: Tracer provider instance that can be used to fetch a tracer.\n        set_logging_format: When set to True, it calls logging.basicConfig() and sets a logging format.\n        logging_format: Accepts a string and sets it as the logging format when set_logging_format\n            is set to True.\n        log_level: Accepts one of the following values and sets the logging level to it.\n            logging.INFO\n            logging.DEBUG\n            logging.WARN\n            logging.ERROR\n            logging.FATAL\n        log_hook: execute custom logic when record is created\n\n    See `BaseInstrumentor`\n    \"\"\"\n\n    _old_factory = None\n    _log_hook = None\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        provider = kwargs.get(\"tracer_provider\", None) or get_tracer_provider()\n        old_factory = logging.getLogRecordFactory()\n        LoggingInstrumentor._old_factory = old_factory\n        LoggingInstrumentor._log_hook = kwargs.get(\"log_hook\", None)\n\n        service_name = None\n\n        def record_factory(*args, **kwargs):\n            record = old_factory(*args, **kwargs)\n\n            record.otelSpanID = \"0\"\n            record.otelTraceID = \"0\"\n\n            nonlocal service_name\n            if service_name is None:\n                resource = getattr(provider, \"resource\", None)\n                if resource:\n                    service_name = (\n                        resource.attributes.get(\"service.name\") or \"\"\n                    )\n                else:\n                    service_name = \"\"\n\n            record.otelServiceName = service_name\n\n            span = get_current_span()\n            if span != INVALID_SPAN:\n                ctx = span.get_span_context()\n                if ctx != INVALID_SPAN_CONTEXT:\n                    record.otelSpanID = format(ctx.span_id, \"016x\")\n                    record.otelTraceID = format(ctx.trace_id, \"032x\")\n                    if callable(LoggingInstrumentor._log_hook):\n                        try:\n                            LoggingInstrumentor._log_hook(  # pylint: disable=E1102\n                                span, record\n                            )\n                        except Exception:  # pylint: disable=W0703\n                            pass\n\n            return record\n\n        logging.setLogRecordFactory(record_factory)\n\n        set_logging_format = kwargs.get(\n            \"set_logging_format\",\n            environ.get(OTEL_PYTHON_LOG_CORRELATION, \"false\").lower()\n            == \"true\",\n        )\n\n        if set_logging_format:\n            log_format = kwargs.get(\n                \"logging_format\", environ.get(OTEL_PYTHON_LOG_FORMAT, None)\n            )\n            log_format = log_format or DEFAULT_LOGGING_FORMAT\n\n            log_level = kwargs.get(\n                \"log_level\", LEVELS.get(environ.get(OTEL_PYTHON_LOG_LEVEL))\n            )\n            log_level = log_level or logging.INFO\n\n            logging.basicConfig(format=log_format, level=log_level)\n\n    def _uninstrument(self, **kwargs):\n        if LoggingInstrumentor._old_factory:\n            logging.setLogRecordFactory(LoggingInstrumentor._old_factory)\n            LoggingInstrumentor._old_factory = None\n", "path": "instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__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\nDEFAULT_LOGGING_FORMAT = \"%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s\"\n\n\n_MODULE_DOC = \"\"\"\nThe OpenTelemetry ``logging`` integration automatically injects tracing context into log statements.\n\nThe integration registers a custom log record factory with the the standard library logging module that automatically inject\ntracing context into log record objects. Optionally, the integration can also call ``logging.basicConfig()`` to set a logging\nformat with placeholders for span ID, trace ID and service name.\n\nThe following keys are injected into log record objects by the factory:\n\n- ``otelSpanID``\n- ``otelTraceID``\n- ``otelServiceName``\n- ``otelTraceSampled``\n\nThe integration uses the following logging format by default:\n\n.. code-block::\n\n    {default_logging_format}\n\nEnable trace context injection\n------------------------------\n\nThe integration is opt-in and must be enabled explicitly by setting the environment variable ``OTEL_PYTHON_LOG_CORRELATION`` to ``true``.\n\nThe integration always registers the custom factory that injects the tracing context into the log record objects. Setting\n``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` calls ``logging.basicConfig()`` to set a logging format that actually makes\nuse of the injected variables.\n\n\nEnvironment variables\n---------------------\n\n.. envvar:: OTEL_PYTHON_LOG_CORRELATION\n\nThis env var must be set to ``true`` in order to enable trace context injection into logs by calling ``logging.basicConfig()`` and\nsetting a logging format that makes use of the injected tracing variables.\n\nAlternatively, ``set_logging_format`` argument can be set to ``True`` when initializing the ``LoggingInstrumentor`` class to achieve the\nsame effect.\n\n.. code-block::\n\n    LoggingInstrumentor(set_logging_format=True)\n\nThe default value is ``false``.\n\n.. envvar:: OTEL_PYTHON_LOG_FORMAT\n\nThis env var can be used to instruct the instrumentation to use a custom logging format.\n\nAlternatively, a custom logging format can be passed to the ``LoggingInstrumentor`` as the ``logging_format`` argument. For example:\n\n.. code-block::\n\n    LoggingInstrumentor(logging_format='%(msg)s [span_id=%(span_id)s]')\n\n\nThe default value is:\n\n.. code-block::\n\n    {default_logging_format}\n\n.. envvar:: OTEL_PYTHON_LOG_LEVEL\n\nThis env var can be used to set a custom logging level.\n\nAlternatively, log level can be passed to the ``LoggingInstrumentor`` during initialization. For example:\n\n.. code-block::\n\n    LoggingInstrumentor(log_level=logging.DEBUG)\n\n\nThe default value is ``info``.\n\nOptions are:\n\n- ``info``\n- ``error``\n- ``debug``\n- ``warning``\n\nManually calling logging.basicConfig\n------------------------------------\n\n``logging.basicConfig()`` can be called to set a global logging level and format. Only the first ever call has any effect on the global logger.\nAny subsequent calls have no effect and do not override a previously configured global logger. This integration calls ``logging.basicConfig()`` for you\nwhen ``OTEL_PYTHON_LOG_CORRELATION`` is set to ``true``. It uses the format and level specified by ``OTEL_PYTHON_LOG_FORMAT`` and ``OTEL_PYTHON_LOG_LEVEL``\nenvironment variables respectively.\n\nIf you code or some other library/framework you are using calls logging.basicConfig before this integration is enabled, then this integration's logging\nformat will not be used and log statements will not contain tracing context. For this reason, you'll need to make sure this integration is enabled as early\nas possible in the service lifecycle or your framework is configured to use a logging format with placeholders for tracing context. This can be achieved by\nadding the following placeholders to your logging format:\n\n.. code-block::\n\n    %(otelSpanID)s %(otelTraceID)s %(otelServiceName)s %(otelTraceSampled)s\n\n\n\nAPI\n-----\n\n.. code-block:: python\n\n    from opentelemetry.instrumentation.logging import LoggingInstrumentor\n\n    LoggingInstrumentor().instrument(set_logging_format=True)\n\n\nNote\n-----\n\nIf you do not set ``OTEL_PYTHON_LOG_CORRELATION`` to ``true`` but instead set the logging format manually or through your framework, you must ensure that this\nintegration is enabled before you set the logging format. This is important because unless the integration is enabled, the tracing context variables\nare not injected into the log record objects. This means any attempted log statements made after setting the logging format and before enabling this integration\nwill result in KeyError exceptions. Such exceptions are automatically swallowed by the logging module and do not result in crashes but you may still lose out\non important log messages.\n\"\"\".format(\n    default_logging_format=DEFAULT_LOGGING_FORMAT\n)\n", "path": "instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/constants.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# pylint: disable=empty-docstring,no-value-for-parameter,no-member,no-name-in-module\n\nimport logging  # pylint: disable=import-self\nfrom os import environ\nfrom typing import Collection\n\nfrom opentelemetry.instrumentation.instrumentor import BaseInstrumentor\nfrom opentelemetry.instrumentation.logging.constants import (\n    _MODULE_DOC,\n    DEFAULT_LOGGING_FORMAT,\n)\nfrom opentelemetry.instrumentation.logging.environment_variables import (\n    OTEL_PYTHON_LOG_CORRELATION,\n    OTEL_PYTHON_LOG_FORMAT,\n    OTEL_PYTHON_LOG_LEVEL,\n)\nfrom opentelemetry.instrumentation.logging.package import _instruments\nfrom opentelemetry.trace import (\n    INVALID_SPAN,\n    INVALID_SPAN_CONTEXT,\n    get_current_span,\n    get_tracer_provider,\n)\n\n__doc__ = _MODULE_DOC\n\nLEVELS = {\n    \"debug\": logging.DEBUG,\n    \"info\": logging.INFO,\n    \"warning\": logging.WARNING,\n    \"error\": logging.ERROR,\n}\n\n\nclass LoggingInstrumentor(BaseInstrumentor):  # pylint: disable=empty-docstring\n    __doc__ = f\"\"\"An instrumentor for stdlib logging module.\n\n    This instrumentor injects tracing context into logging records and optionally sets the global logging format to the following:\n\n    .. code-block::\n\n        {DEFAULT_LOGGING_FORMAT}\n\n        def log_hook(span: Span, record: LogRecord):\n                if span and span.is_recording():\n                    record.custom_user_attribute_from_log_hook = \"some-value\"\n\n    Args:\n        tracer_provider: Tracer provider instance that can be used to fetch a tracer.\n        set_logging_format: When set to True, it calls logging.basicConfig() and sets a logging format.\n        logging_format: Accepts a string and sets it as the logging format when set_logging_format\n            is set to True.\n        log_level: Accepts one of the following values and sets the logging level to it.\n            logging.INFO\n            logging.DEBUG\n            logging.WARN\n            logging.ERROR\n            logging.FATAL\n        log_hook: execute custom logic when record is created\n\n    See `BaseInstrumentor`\n    \"\"\"\n\n    _old_factory = None\n    _log_hook = None\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        provider = kwargs.get(\"tracer_provider\", None) or get_tracer_provider()\n        old_factory = logging.getLogRecordFactory()\n        LoggingInstrumentor._old_factory = old_factory\n        LoggingInstrumentor._log_hook = kwargs.get(\"log_hook\", None)\n\n        service_name = None\n\n        def record_factory(*args, **kwargs):\n            record = old_factory(*args, **kwargs)\n\n            record.otelSpanID = \"0\"\n            record.otelTraceID = \"0\"\n            record.otelTraceSampled = False\n\n            nonlocal service_name\n            if service_name is None:\n                resource = getattr(provider, \"resource\", None)\n                if resource:\n                    service_name = (\n                        resource.attributes.get(\"service.name\") or \"\"\n                    )\n                else:\n                    service_name = \"\"\n\n            record.otelServiceName = service_name\n\n            span = get_current_span()\n            if span != INVALID_SPAN:\n                ctx = span.get_span_context()\n                if ctx != INVALID_SPAN_CONTEXT:\n                    record.otelSpanID = format(ctx.span_id, \"016x\")\n                    record.otelTraceID = format(ctx.trace_id, \"032x\")\n                    record.otelTraceSampled = ctx.trace_flags.sampled\n                    if callable(LoggingInstrumentor._log_hook):\n                        try:\n                            LoggingInstrumentor._log_hook(  # pylint: disable=E1102\n                                span, record\n                            )\n                        except Exception:  # pylint: disable=W0703\n                            pass\n\n            return record\n\n        logging.setLogRecordFactory(record_factory)\n\n        set_logging_format = kwargs.get(\n            \"set_logging_format\",\n            environ.get(OTEL_PYTHON_LOG_CORRELATION, \"false\").lower()\n            == \"true\",\n        )\n\n        if set_logging_format:\n            log_format = kwargs.get(\n                \"logging_format\", environ.get(OTEL_PYTHON_LOG_FORMAT, None)\n            )\n            log_format = log_format or DEFAULT_LOGGING_FORMAT\n\n            log_level = kwargs.get(\n                \"log_level\", LEVELS.get(environ.get(OTEL_PYTHON_LOG_LEVEL))\n            )\n            log_level = log_level or logging.INFO\n\n            logging.basicConfig(format=log_format, level=log_level)\n\n    def _uninstrument(self, **kwargs):\n        if LoggingInstrumentor._old_factory:\n            logging.setLogRecordFactory(LoggingInstrumentor._old_factory)\n            LoggingInstrumentor._old_factory = None\n", "path": "instrumentation/opentelemetry-instrumentation-logging/src/opentelemetry/instrumentation/logging/__init__.py"}]}