Node.js، Python، Go و زبانهای دیگر
در این آموزش
هر زبانی که کتابخانهٔ OpenTelemetry دارد، از جمله Node.js، Python، Go، PHP، Ruby و Rust، با پروتکل OTLP/HTTP به LogMug وصل میشود. در این برگه اول متغیرهای محیطی مشترک را میگذاریم و بعد برای سه زبان رایجتر گامهای دقیق را میآوریم. اگر زبان یا محیطی کتابخانهٔ OpenTelemetry ندارد، ارسال با HTTP و JSON همیشه کار میکند.
متغیرهای محیطی مشترک
این متغیرها در مشخصات OpenTelemetry استاندارد شدهاند و SDK همهٔ زبانها آنها را میخوانند:
OTEL_SERVICE_NAME=billing
OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production
OTEL_LOGS_EXPORTER=otlp
OTEL_TRACES_EXPORTER=none
OTEL_METRICS_EXPORTER=none
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://ingest.logmug.ir/v1/logs
OTEL_EXPORTER_OTLP_LOGS_HEADERS=x-logmug-key=lm_ingest_...
- LogMug فقط لاگ میپذیرد؛ برای همین exporter trace و metric را
noneمیگذاریم. - متغیر
..._LOGS_ENDPOINTنشانی کامل است و باید/v1/logsداشته باشد. اگر بهجای آنOTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.logmug.irبدهید، SDK خودش مسیر را اضافه میکند. - هدر به شکل
نام=مقدارنوشته میشود و کلید را در یک secret نگه دارید، نه در مخزن کد.
Node.js
با بستهٔ auto-instrumentations، لاگهای pino (نسخهٔ 7 به بعد) و winston (نسخهٔ 3) خودکار فرستاده میشوند:
npm install --save @opentelemetry/api @opentelemetry/auto-instrumentations-node
# only if you use winston:
npm install --save @opentelemetry/winston-transport
متغیرهای بالا را تنظیم کنید و برنامه را با --require اجرا کنید:
node --require @opentelemetry/auto-instrumentations-node/register app.js
یا در محیطی که دستور اجرا دست شما نیست:
NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
یک نمونه با pino؛ کد لاگنویسی هیچ تغییری نمیکند:
const pino = require('pino');
const logger = pino();
logger.info({ orderId: 991 }, 'order created');
logger.error({ err: new Error('card declined'), orderId: 991 }, 'payment failed');
توجه کنید که console.log گرفته نمیشود؛ فقط لاگهایی که از pino یا winston (یا مستقیم از Logs API در OpenTelemetry) بگذرند.
Python
با بستهٔ distro و اجرای برنامه از طریق opentelemetry-instrument، ماژول استاندارد logging به LogMug وصل میشود:
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
علاوه بر متغیرهای مشترک، این دو را هم بگذارید:
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
opentelemetry-instrument python app.py
در نسخههای جدید OpenTelemetry Python گرفتن خودکار لاگ بهطور پیشفرض روشن است و متغیر دوم فقط برای نسخههای قدیمیتر لازم است؛ گذاشتنش ضرری ندارد. سطح logger ریشهٔ Python بهطور پیشفرض WARNING است، پس اگر لاگهای info را هم میخواهید سطح را پایین بیاورید:
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger("billing")
log.info("invoice created", extra={"invoice_id": 5512})
try:
1 / 0
except ZeroDivisionError:
log.exception("invoice total failed")
مقادیر extra ویژگی قابلفیلتر میشوند و log.exception نوع و stack trace خطا را جدا میفرستد. برای Django و Flask همین روش با opentelemetry-instrument جلوی gunicorn یا uwsgi کار میکند.
Go
Go ابزار بدونکد برای لاگ ندارد؛ چند خط کد لازم است. با پل otelslog، پکیج استاندارد log/slog به OpenTelemetry وصل میشود (بخش لاگ OpenTelemetry Go هنوز در مرحلهٔ beta است):
go get go.opentelemetry.io/otel/sdk/log \
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp \
go.opentelemetry.io/contrib/bridges/otelslog
package main
import (
"context"
"go.opentelemetry.io/contrib/bridges/otelslog"
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
sdklog "go.opentelemetry.io/otel/sdk/log"
)
func main() {
ctx := context.Background()
// Reads OTEL_EXPORTER_OTLP_LOGS_ENDPOINT and _HEADERS from the environment.
exp, err := otlploghttp.New(ctx)
if err != nil {
panic(err)
}
provider := sdklog.NewLoggerProvider(
sdklog.WithProcessor(sdklog.NewBatchProcessor(exp)),
)
defer provider.Shutdown(ctx) // flushes the last batch
logger := otelslog.NewLogger("billing", otelslog.WithLoggerProvider(provider))
logger.InfoContext(ctx, "invoice created", "invoice_id", 5512)
}
نام سرویس از OTEL_SERVICE_NAME خوانده میشود. از نسخههای ...Context مثل InfoContext استفاده کنید تا اگر در context یک span باشد، trace_id روی لاگ بنشیند.
PHP، Ruby، Rust و بقیه
برای این زبانها هم SDK رسمی OpenTelemetry همان متغیرهای مشترک را میخواند؛ کافی است پل (bridge) کتابخانهٔ لاگ آن زبان را طبق مستندات OpenTelemetry همان زبان نصب کنید. اگر نصب SDK برای کارتان زیادی است، فرستادن JSON با endpoint ساده از هر زبانی در چند خط شدنی است.
عیبیابی
- هیچ درخواستی نمیرسد: پروتکل روی gRPC مانده است (پیشفرض برخی SDKها) یا
/v1/logsاز انتهای..._LOGS_ENDPOINTافتاده است. موقتاًOTEL_LOGS_EXPORTER=consoleبگذارید تا ببینید اصلاً لاگی تولید میشود یا نه. 401: کلید نادرست یا باطلشده است، یا هدر به شکلx-logmug-key=...نوشته نشده است.400: بدنه خوانده نشد؛ پروتکل راhttp/protobufبگذارید.403: سهمیهٔ ماهانهٔ پلن رایگان تمام شده است.429و503: عبور از نرخ مجاز یا شلوغی موقت؛ پاسخRetry-Afterدارد و exporterها دوباره تلاش میکنند.- لاگهای آخر برنامههای کوتاهعمر (اسکریپت، job) نمیرسند: پیش از خروج provider را
Shutdownیاflushکنید.
منابع و مطالعهٔ بیشتر
- متغیرهای محیطی OTLP exporter — مرجع مشترک همهٔ زبانها.
- OpenTelemetry بدون کد در Python — جزئیات
opentelemetry-instrumentو گزینههایش. - OpenTelemetry برای Go — وضعیت SDK لاگ و نمونههای رسمی.
کلید پروژهتان را هنوز ندارید؟
در پلن رایگان یک پروژه بسازید؛ راهنمای اتصال با نشانی و کلید واقعی خودتان همانجا آماده است.
شروع رایگان