Dağıtık sistemlerde hata ayıklarken genellikle bir izden başlarsınız ve ilgili günlük kayıtlarına ihtiyaç duyarsınız; bazen de tam tersi durum geçerlidir. OpenTelemetry iz kimliklerini (trace ID) ve span kimliklerini (span ID) uygulama günlüklerinize ekleyerek, bir iz span'ından o işlem sırasında üretilen kesin günlük satırlarına hızlıca geçiş yapabilirsiniz. Bu yaklaşım, arıza teşhisini ve performans analizini hızlandırır.
Bu konu, Java, Go ve Python için iz-günlük ilişkisini ele alır. Java ve Python, OpenTelemetry otomatik enstrümantasyonu aracılığıyla otomatik ekleme özelliğini destekler. Go ise manuel ekleme gerektirir.
Ön koşullar
Başlamadan önce şunlara sahip olduğunuzdan emin olun:
OpenTelemetry izleme özelliği etkinleştirilmiş şekilde ARMS tarafından izlenen uygulamanız
Kullandığınız dile bağlı olarak yüklü OpenTelemetry Java ajanı, Go SDK veya Python SDK
Nasıl çalışır
OpenTelemetry, aktif bir span içinde üretilen her günlük kaydına trace_id ve span_id değerlerini enjekte etmek için Eşlenmiş Tanılama Bağlamını (Mapped Diagnostic Context - MDC) kullanır. Otomatik enstrümantasyonla (Java, Python) ajan, ekleme işlemini otomatik olarak yönetir; kod değişikliği gerekmez. Otomatik enstrümantasyon olmadığında (Go), bu değerleri span bağlamından çıkarmanız ve günlük alanlarına manuel olarak eklemeniz gerekir.
İz bağlamı günlüklerinizde göründükten sonra, belirli bir isteğe ait tüm günlük kayıtlarını bulmak için Simple Log Service üzerinde iz kimliğine göre arama yapabilirsiniz.
Java
Desteklenen günlük çerçeveleri
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MDC otomatik enstrümantasyonunun nasıl çalıştığına ilişkin ayrıntılar için bkz. Logger MDC auto-instrumentation.
Log4j 2'yi yapılandırın
-
OpenTelemetry Log4j 2 bağımlılığını
pom.xmldosyanıza ekleyin.OPENTELEMETRY_VERSIONyerine en son sürümü yazın.<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-log4j-context-data-2.17-autoconfigure</artifactId> <version>OPENTELEMETRY_VERSION</version> <scope>runtime</scope> </dependency> </dependencies> -
%X{trace_id}ve%X{span_id}ifadelerinilog4j2.xmldosyasındaki desene ekleyin.%X{key}sözdizimi, MDC'den değerleri okur; OpenTelemetry ajanı, bir span aktif olduğunda bu değerleri otomatik olarak doldurur.<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} - %msg%n"/> </Console> </Appenders> <Loggers> <Root> <AppenderRef ref="Console" level="All"/> </Root> </Loggers> </Configuration>
Logback'i yapılandırın
-
OpenTelemetry Logback bağımlılığını
pom.xmldosyanıza ekleyin.OPENTELEMETRY_VERSIONyerine en son sürümü yazın.<dependencies> <dependency> <groupId>io.opentelemetry.instrumentation</groupId> <artifactId>opentelemetry-logback-mdc-1.0</artifactId> <version>OPENTELEMETRY_VERSION</version> </dependency> </dependencies> -
Desene
%X{trace_id}ve%X{span_id}ifadelerini dahil etmek ve appenders'ınızıOpenTelemetryAppenderile sarmak içinlogback.xmldosyasını güncelleyin.<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} trace_id=%X{trace_id} span_id=%X{span_id} trace_flags=%X{trace_flags} %msg%n</pattern> </encoder> </appender> <!-- Wrap your logging appender with OpenTelemetryAppender --> <appender name="OTEL" class="io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender"> <appender-ref ref="CONSOLE"/> </appender> <!-- Use the wrapped "OTEL" appender instead of the original "CONSOLE" one --> <root level="INFO"> <appender-ref ref="OTEL"/> </root> </configuration>
Spring Boot'ta Logback'i yapılandırın
Spring Boot varsayılan olarak Logback kullanır. XML dosyasını düzenlemek yerine, application.properties dosyasına tek bir satır ekleyin:
logging.pattern.level=trace_id=%mdc{trace_id} span_id=%mdc{span_id} %5p
Örnek çıktı:
2024-06-26 10:56:31.200 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-06-26 10:56:31.201 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-06-26 10:56:31.209 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=1b08f18b8858bb9a INFO 53724 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms
2024-06-26 10:56:31.296 trace_id=8f7ebd8a73f9a8f50e6a00a87a20952a span_id=5743699405074f4e INFO 53724 --- [nio-8081-exec-1] com.example.httpserver.ot.OTServer : hello world
Go
Go'daki OpenTelemetry, günlüklerde otomatik iz bağlamı enjeksiyonunu desteklemez. İz kimliklerini ve span kimliklerini span bağlamından manuel olarak çıkarın.
logrus'u yapılandırın
-
Gerekli paketleri içe aktarın.
import ( oteltrace "go.opentelemetry.io/otel/trace" "github.com/sirupsen/logrus" ) -
Bir spandan iz kimliklerini ve span kimliklerini çıkaran ve bunları logrus alanları olarak döndüren bir yardımcı işlev oluşturun.
func LogrusFields(span oteltrace.Span) logrus.Fields { return logrus.Fields{ "trace_id": span.SpanContext().TraceID().String(), "span_id": span.SpanContext().SpanID().String(), } } -
İz bağlamıyla günlük kaydı oluşturmak için bir span oluşturduktan sonra yardımcı işlevi kullanın.
_, span := tracer.Start(ctx, "spanName") defer span.End() logEntry := logrus.WithFields(LogrusFields(span)) logEntry.Info("This is an info message with trace and span ID")
Python
Python'daki OpenTelemetry, günlüklerde otomatik iz bağlamı enjeksiyonunu destekler. Ayrıntılar için bkz. OpenTelemetry Logging Instrumentation.
Günlük modülünü yapılandırın
-
Aşağıdaki ortam değişkenini ayarlayarak otomatik enjeksiyonu etkinleştirin:
export OTEL_PYTHON_LOG_CORRELATION=true -
Günlük biçiminize
%(otelTraceID)sve%(otelSpanID)sifadelerini ekleyin. OpenTelemetry, çalışma zamanında bu yer tutucuları gerçek iz kimliği ve span kimliğiyle değiştirir.Günlük biçimi örneği:
formatter = logging.Formatter( '%(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' )Örnek çıktı:
2024-06-25 10:00:55,494 INFO [app] [test.py:80] [trace_id=70561de6a164ac991bfff2281b7f**** span_id=4b7f3c798460**** resource.service.name=ot-python-demo] - hello world
Flask ile uçtan uca örnek
Bu örnek, tam bir kurulum sürecini adım adım gösterir: Bir Flask uygulaması oluşturma, bunu OpenTelemetry ile enstrümante etme ve iz kimliklerinin günlüklerde göründüğünü doğrulama.
Ön koşullar:
Yüklü Python ve pip (bu örnekte Python 3.12.4 ve pip 24.1.1 kullanılmıştır)
1. Adım: Bağımlılıkları yükleyin
Flask'ı yükleyin:
pip3 install flask
OpenTelemetry dağıtımını ve otomatik enstrümantasyon kitaplıklarını yükleyin:
pip3 install opentelemetry-distro \
opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
2. Adım: Uygulamayı oluşturun
Aşağıdaki kodu test.py olarak kaydedin:
import logging
from logging.handlers import RotatingFileHandler
from flask import Flask
app = Flask(__name__)
# Create a formatter that includes OpenTelemetry trace context
formatter = logging.Formatter(
'%(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'
)
# Write logs to a file with rotation
# Replace <log-file-path> with the actual path, for example: /var/log/app.log
file_handler = RotatingFileHandler('<log-file-path>', maxBytes=10000, backupCount=1)
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
app.logger.addHandler(file_handler)
@app.route('/')
def hello_world():
app.logger.info('Hello World!!!')
return 'Hello, World!'
if __name__ == '__main__':
app.run()
3. Adım: Uygulamayı OpenTelemetry enstrümantasyonu ile çalıştırın
Ortam değişkenlerini ayarlayın ve uygulamayı OpenTelemetry otomatik enstrümantasyon sarmalayıcısı ile başlatın:
export OTEL_PYTHON_LOG_CORRELATION=true
export OTEL_SERVICE_NAME=ot-python-demo
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=none
# Replace test.py with your actual filename if different
opentelemetry-instrument python3 test.py
Uygulama başarıyla başlarsa, aşağıdakine benzer bir çıktı görünür:
* Running on http://127.0.**.**:5000
4. Adım: Günlük çıktısını doğrulayın
Uygulamaya bir istek gönderin ve günlük dosyasını kontrol edin. Her giriş artık iz kimliğini ve span kimliğini içerir:
2024-06-25 10:00:55,494 INFO [app] [test.py:80] [trace_id=70561de6a164ac991bfff2281b7f**** span_id=4b7f3c798460**** resource.service.name=ot-python-demo] - hello world
Sırada ne var
Günlükleri izlerle ilişkilendirin -- ARMS konsolunda günlük kayıtlarından dağıtık izlere gidin.
Uygulama günlüklerini Simple Log Service'te iz kimlikleriyle ilişkilendirin -- ARMS izleri ile Simple Log Service günlükleri arasında çift yönlü ilişki kurulumu yapın.