1515
1616import abc
1717import logging
18- import logging .config
19- import threading
2018import typing
21- import opentelemetry .sdk .util .instrumentation as otel_instrumentation
22- import opentelemetry .sdk ._logs ._internal as _logs_internal
2319
2420from snowflake .telemetry ._internal .opentelemetry .exporter .otlp .proto .common ._log_encoder import (
2521 encode_logs ,
@@ -84,7 +80,6 @@ class SnowflakeLoggingHandler(_logs.LoggingHandler):
8480 discarded by the original implementation.
8581 """
8682
87- LOGGER_NAME_TEMP_ATTRIBUTE : typing .Final = "__snow.logging.temp.logger_name"
8883 CODE_FILEPATH : typing .Final = "code.filepath"
8984 CODE_FILE_PATH : typing .Final = "code.file.path"
9085 CODE_FUNCTION : typing .Final = "code.function"
@@ -97,9 +92,10 @@ def __init__(
9792 log_writer : LogWriter ,
9893 ):
9994 exporter = _ProtoLogExporter (log_writer )
100- provider = _SnowflakeTelemetryLoggerProvider ()
101- provider .add_log_record_processor (
102- export .SimpleLogRecordProcessor (exporter )
95+ processor = export .SimpleLogRecordProcessor (exporter )
96+ provider = _logs .LoggerProvider (
97+ resource = Resource .get_empty (),
98+ multi_log_record_processor = processor
10399 )
104100 super ().__init__ (logger_provider = provider )
105101
@@ -118,12 +114,6 @@ def _get_attributes(record: logging.LogRecord) -> types.Attributes:
118114 if SnowflakeLoggingHandler .CODE_LINE_NUMBER in attributes :
119115 attributes [SnowflakeLoggingHandler .CODE_LINENO ] = attributes .pop (SnowflakeLoggingHandler .CODE_LINE_NUMBER )
120116
121- # Temporarily storing logger's name in record's attributes.
122- # This attribute will be removed by the logger.
123- #
124- # TODO (SNOW-1235374): opentelemetry-python issue #2485: Record logger
125- # name as the instrumentation scope name
126- attributes [SnowflakeLoggingHandler .LOGGER_NAME_TEMP_ATTRIBUTE ] = record .name
127117 return attributes
128118
129119 def _translate (self , record : logging .LogRecord ) -> _logs .LogRecord :
@@ -132,75 +122,6 @@ def _translate(self, record: logging.LogRecord) -> _logs.LogRecord:
132122 return otel_record
133123
134124
135- class _SnowflakeTelemetryLogger (_logs .Logger ):
136- """
137- An Open Telemetry Logger which creates an InstrumentationScope for each
138- logger name it encounters.
139- """
140-
141- def __init__ (
142- self ,
143- resource : Resource ,
144- multi_log_record_processor : typing .Union [
145- _logs_internal .SynchronousMultiLogRecordProcessor ,
146- _logs_internal .ConcurrentMultiLogRecordProcessor ,
147- ],
148- instrumentation_scope : otel_instrumentation .InstrumentationScope ,
149- ):
150- super ().__init__ (resource , multi_log_record_processor , instrumentation_scope )
151- self ._lock = threading .Lock ()
152- self .cached_scopes = {}
153-
154- def emit (self , record : _logs .LogRecord ):
155- if SnowflakeLoggingHandler .LOGGER_NAME_TEMP_ATTRIBUTE not in record .attributes :
156- # The record doesn't contain our custom attribute with a logger name,
157- # so we can call the superclass's `emit` method. It will emit a log
158- # record with the default instrumentation scope.
159- super ().emit (record )
160- return
161-
162- # Creating an InstrumentationScope for each logger name,
163- # and caching those scopes.
164- logger_name = record .attributes [SnowflakeLoggingHandler .LOGGER_NAME_TEMP_ATTRIBUTE ]
165- del record .attributes [SnowflakeLoggingHandler .LOGGER_NAME_TEMP_ATTRIBUTE ]
166- with self ._lock :
167- if logger_name in self .cached_scopes :
168- current_scope = self .cached_scopes [logger_name ]
169- else :
170- current_scope = otel_instrumentation .InstrumentationScope (logger_name )
171- self .cached_scopes [logger_name ] = current_scope
172-
173- # Emitting a record with a scope that corresponds to the logger
174- # that logged it. NOT calling the superclass here for two reasons:
175- # 1. Logger.emit takes a LogRecord, not LogData.
176- # 2. It would emit a log record with the default instrumentation scope,
177- # not with the scope we want.
178- log_data = _logs .LogData (record , current_scope )
179- self ._multi_log_record_processor .on_emit (log_data )
180-
181-
182- class _SnowflakeTelemetryLoggerProvider (_logs .LoggerProvider ):
183- """
184- A LoggerProvider that creates SnowflakeTelemetryLoggers
185- """
186-
187- def get_logger (
188- self , name : str ,
189- version : types .Optional [str ] = None ,
190- schema_url : types .Optional [str ] = None ,
191- attributes : types .Optional [types .Attributes ] = None ,
192- ) -> _logs .Logger :
193- return _SnowflakeTelemetryLogger (
194- Resource .get_empty (),
195- self ._multi_log_record_processor ,
196- otel_instrumentation .InstrumentationScope (
197- name ,
198- version ,
199- schema_url ,
200- ),
201- )
202-
203-
204125__all__ = [
205126 "LogWriter" ,
206127 "SnowflakeLoggingHandler" ,
0 commit comments