Skip to content

Commit b41c6e3

Browse files
srikanthccvAlex Boten
authored and
Alex Boten
committed
Add initial overall structure and classes for logs sdk (open-telemetry#1894)
1 parent c7c249f commit b41c6e3

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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+
import abc
16+
import atexit
17+
from typing import Any, Optional
18+
19+
from opentelemetry.sdk.logs.severity import SeverityNumber
20+
from opentelemetry.sdk.resources import Resource
21+
from opentelemetry.sdk.util.instrumentation import InstrumentationInfo
22+
from opentelemetry.trace.span import TraceFlags
23+
from opentelemetry.util.types import Attributes
24+
25+
26+
class LogRecord:
27+
"""A LogRecord instance represents an event being logged.
28+
29+
LogRecord instances are created and emitted via `LogEmitter`
30+
every time something is logged. They contain all the information
31+
pertinent to the event being logged.
32+
"""
33+
34+
def __init__(
35+
self,
36+
timestamp: Optional[int] = None,
37+
trace_id: Optional[int] = None,
38+
span_id: Optional[int] = None,
39+
trace_flags: Optional[TraceFlags] = None,
40+
severity_text: Optional[str] = None,
41+
severity_number: Optional[SeverityNumber] = None,
42+
name: Optional[str] = None,
43+
body: Optional[Any] = None,
44+
resource: Optional[Resource] = None,
45+
attributes: Optional[Attributes] = None,
46+
):
47+
self.timestamp = timestamp
48+
self.trace_id = trace_id
49+
self.span_id = span_id
50+
self.trace_flags = trace_flags
51+
self.severity_text = severity_text
52+
self.severity_number = severity_number
53+
self.name = name
54+
self.body = body
55+
self.resource = resource
56+
self.attributes = attributes
57+
58+
def __eq__(self, other: object) -> bool:
59+
if not isinstance(other, LogRecord):
60+
return NotImplemented
61+
return self.__dict__ == other.__dict__
62+
63+
64+
class LogData:
65+
"""Readable LogRecord data plus associated InstrumentationLibrary."""
66+
67+
def __init__(
68+
self,
69+
log_record: LogRecord,
70+
instrumentation_info: InstrumentationInfo,
71+
):
72+
self.log_record = log_record
73+
self.instrumentation_info = instrumentation_info
74+
75+
76+
class LogProcessor(abc.ABC):
77+
"""Interface to hook the log record emitting action.
78+
79+
Log processors can be registered directly using
80+
:func:`LogEmitterProvider.add_log_processor` and they are invoked
81+
in the same order as they were registered.
82+
"""
83+
84+
@abc.abstractmethod
85+
def emit(self, log_data: LogData):
86+
"""Emits the `LogData`"""
87+
88+
@abc.abstractmethod
89+
def shutdown(self):
90+
"""Called when a :class:`opentelemetry.sdk.logs.LogEmitter` is shutdown"""
91+
92+
@abc.abstractmethod
93+
def force_flush(self, timeout_millis: int = 30000):
94+
"""Export all the received logs to the configured Exporter that have not yet
95+
been exported.
96+
97+
Args:
98+
timeout_millis: The maximum amount of time to wait for logs to be
99+
exported.
100+
101+
Returns:
102+
False if the timeout is exceeded, True otherwise.
103+
"""
104+
105+
106+
class LogEmitter:
107+
# TODO: Add multi_log_processor
108+
def __init__(
109+
self,
110+
resource: Resource,
111+
instrumentation_info: InstrumentationInfo,
112+
):
113+
self._resource = resource
114+
self._instrumentation_info = instrumentation_info
115+
116+
def emit(self, record: LogRecord):
117+
# TODO: multi_log_processor.emit
118+
pass
119+
120+
def flush(self):
121+
# TODO: multi_log_processor.force_flush
122+
pass
123+
124+
125+
class LogEmitterProvider:
126+
# TODO: Add multi_log_processor
127+
def __init__(
128+
self,
129+
resource: Resource = Resource.create(),
130+
shutdown_on_exit: bool = True,
131+
):
132+
self._resource = resource
133+
self._at_exit_handler = None
134+
if shutdown_on_exit:
135+
self._at_exit_handler = atexit.register(self.shutdown)
136+
137+
def get_log_emitter(
138+
self,
139+
instrumenting_module_name: str,
140+
instrumenting_module_verison: str = "",
141+
) -> LogEmitter:
142+
return LogEmitter(
143+
self._resource,
144+
InstrumentationInfo(
145+
instrumenting_module_name, instrumenting_module_verison
146+
),
147+
)
148+
149+
def add_log_processor(self, log_processor: LogProcessor):
150+
"""Registers a new :class:`LogProcessor` for this `LogEmitterProvider` instance.
151+
152+
The log processors are invoked in the same order they are registered.
153+
"""
154+
# TODO: multi_log_processor.add_log_processor.
155+
156+
def shutdown(self):
157+
"""Shuts down the log processors."""
158+
# TODO: multi_log_processor.shutdown
159+
if self._at_exit_handler is not None:
160+
atexit.unregister(self._at_exit_handler)
161+
self._at_exit_handler = None
162+
163+
def force_flush(self, timeout_millis: int = 30000) -> bool:
164+
"""Force flush the log processors.
165+
166+
Args:
167+
timeout_millis: The maximum amount of time to wait for logs to be
168+
exported.
169+
170+
Returns:
171+
True if all the log processors flushes the logs within timeout,
172+
False otherwise.
173+
"""
174+
# TODO: multi_log_processor.force_flush
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
import abc
16+
import enum
17+
from typing import Sequence
18+
19+
from opentelemetry.sdk.logs import LogData
20+
21+
22+
class LogExportResult(enum.Enum):
23+
SUCCESS = 0
24+
FAILURE = 1
25+
26+
27+
class LogExporter(abc.ABC):
28+
"""Interface for exporting logs.
29+
30+
Interface to be implemented by services that want to export logs received
31+
in their own format.
32+
33+
To export data this MUST be registered to the :class`opentelemetry.sdk.logs.LogEmitter` using a
34+
log processor.
35+
"""
36+
37+
@abc.abstractmethod
38+
def export(self, batch: Sequence[LogData]):
39+
"""Exports a batch of logs.
40+
41+
Args:
42+
batch: The list of `LogData` objects to be exported
43+
44+
Returns:
45+
The result of the export
46+
"""
47+
48+
@abc.abstractmethod
49+
def shutdown(self):
50+
"""Shuts down the exporter.
51+
52+
Called when the SDK is shut down.
53+
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
import enum
16+
17+
18+
class SeverityNumber(enum.Enum):
19+
"""Numerical value of severity.
20+
21+
Smaller numerical values correspond to less severe events
22+
(such as debug events), larger numerical values correspond
23+
to more severe events (such as errors and critical events).
24+
25+
See the `Log Data Model`_ spec for more info and how to map the
26+
severity from source format to OTLP Model.
27+
28+
.. _Log Data Model:
29+
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber
30+
"""
31+
32+
UNSPECIFIED = 0
33+
TRACE = 1
34+
TRACE2 = 2
35+
TRACE3 = 3
36+
TRACE4 = 4
37+
DEBUG = 5
38+
DEBUG2 = 6
39+
DEBUG3 = 7
40+
DEBUG4 = 8
41+
INFO = 9
42+
INFO2 = 10
43+
INFO3 = 11
44+
INFO4 = 12
45+
WARN = 13
46+
WARN2 = 14
47+
WARN3 = 15
48+
WARN4 = 16
49+
ERROR = 17
50+
ERROR2 = 18
51+
ERROR3 = 19
52+
ERROR4 = 20
53+
FATAL = 21
54+
FATAL2 = 22
55+
FATAL3 = 23
56+
FATAL4 = 24

0 commit comments

Comments
 (0)